libs-base/Source/NSThread.m
netc 5f7871270a Remove dependency upon config.h by headers files and include
directly in source files because the config.h file is system
dependent, used just for compiling the source, and should
not be installed.
Some minor bug fixes.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@2619 72102866-910b-0410-8b05-ffd578937521
1997-11-06 00:51:23 +00:00

212 lines
5.8 KiB
Objective-C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* Control of executable units within a shared virtual memory space
Copyright (C) 1996 Free Software Foundation, Inc.
Original Author: Scott Christley <scottc@net-community.com>
Rewritten by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: 1996
This file is part of the GNUstep Objective-C Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <config.h>
#include <Foundation/NSThread.h>
#include <Foundation/NSLock.h>
#include <Foundation/NSString.h>
#include <gnustep/base/o_map.h>
#include <gnustep/base/Notification.h>
// Class variables
#define USING_THREAD_COLLECTION 0
#if USING_THREAD_COLLECTION
/* For managing the collection of all NSThread objects. Note, however,
threads that have not yet called +currentThread will not be in the
collection.
xxx Do we really need this collection anyway?
How about getting rid of it? */
static NSRecursiveLock *thread_lock;
static o_map_t thread_id_2_nsthread;
#endif
/* Flag indicating whether the objc runtime ever went multi-threaded. */
static BOOL entered_multi_threaded_state;
@implementation NSThread
// Class initialization
+ (void) initialize
{
if (self == [NSThread class])
{
#if USING_THREAD_COLLECTION
thread_id_2_nsthread = o_map_of_non_owned_void_p ();
thread_lock = [[[NSRecursiveLock alloc] init]
autorelease];
#endif
entered_multi_threaded_state = NO;
}
}
// Initialization
- (void)dealloc
{
[_thread_dictionary release];
[super dealloc];
}
- init
{
[super init];
/* Make it easy and fast to get this NSThread object from the thread. */
objc_thread_set_data (self);
/* initialize our ivars. */
_thread_dictionary = nil; // Initialize this later only when needed
_exception_handler = NULL;
init_autorelease_thread_vars (&_autorelease_vars);
#if USING_THREAD_COLLECTION
/* Register ourselves in the maptable of all threads. */
// Lock the thread list so it doesn't change on us
[thread_lock lock];
// Save the thread in our thread map; NOTE: this will not retain it
o_map_at_key_put_value_known_absent (thread_id_2_nsthread, tid, t);
[thread_lock unlock];
#endif
return self;
}
// Creating an NSThread
+ (NSThread*) currentThread
{
id t = (id) objc_thread_get_data ();
/* If an NSThread object for this thread has already been created
and stashed away, return it. This depends on the objc runtime
initializing objc_thread_get_data() to 0 for newly-created
threads. */
if (t)
return t;
/* We haven't yet created an NSThread object for this thread; create
it. (Doing this here instead of in +detachNewThread.. not only
avoids the race condition, it also nicely provides an NSThread on
request for the single thread that exists at application
start-up, and for thread's created by calling
objc_thread_detach() directly.) */
t = [[NSThread alloc] init];
return t;
}
+ (void) detachNewThreadSelector:(SEL)aSelector
toTarget:(id)aTarget
withObject:(id)anArgument
{
/* Post a notification if this is the first new thread to be created.
Won't work properly if threads are not all created by this class.
xxx Should the notification be done before the new thread starts,
or after? */
if (!entered_multi_threaded_state)
{
entered_multi_threaded_state = YES;
[NotificationDispatcher
postNotificationName: NSBecomingMultiThreaded
object: nil];
}
// Have the runtime detach the thread
objc_thread_detach (aSelector, aTarget, anArgument);
/* NOTE we can't create the new NSThread object for this thread here
because there would be a race condition. The newly created
thread might ask for its NSThread object before we got to create
it. */
}
// Querying a thread
+ (BOOL) isMultiThreaded
{
return entered_multi_threaded_state;
}
/* Thread dictionary
NB. This cannot be autoreleased, since we cannot be sure that the
autorelease pool for the thread will continue to exist for the entire
life of the thread!
*/
- (NSMutableDictionary*) threadDictionary
{
if (!_thread_dictionary)
_thread_dictionary = [NSMutableDictionary new];
return _thread_dictionary;
}
// Delaying a thread
+ (void) sleepUntilDate: (NSDate*)date
{
// xxx Do we need some runtime/OS support for this?
[self notImplemented: _cmd];
}
// Terminating a thread
// What happens if the thread doesn't call +exit?
+ (void) exit
{
NSThread *t;
// the the current NSThread
t = objc_thread_get_data ();
assert (t);
// Post the notification
[NotificationDispatcher
postNotificationName: NSThreadExiting
object: t];
#if USING_THREAD_COLLECTION
{
_objc_thread_t tid;
// Get current thread id from runtime
tid = objc_thread_id();
// Lock the thread list so it doesn't change on us
[thread_lock lock];
// Remove the thread from the map
o_map_remove_key (thread_id_2_nsthread, tid);
// Unlock the thread list
[thread_lock unlock];
}
#endif
// Release the thread object
[t release];
// xxx Clean up any outstanding NSAutoreleasePools here.
// Tell the runtime to exit the thread
objc_thread_exit ();
}
@end