dded nicolas NSThread additions.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@8080 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2000-11-12 07:41:24 +00:00
parent 42ffe0b536
commit b17da14fe9
4 changed files with 172 additions and 1 deletions

View file

@ -1,3 +1,16 @@
Fri Nov 10 12:30:27 2000 Nicola Pero <n.pero@mi.flashnet.it>
Added some GNUstep extensions to NSThread to allow JIGS to
transparently map java threads to gnustep threads (and vice
versa):
* Headers/gnustep/base/NSThread.h, Source/externs.m:
(NSThreadDidStartNotification): New notification.
* Source/NSThread.m ([NSThread -_sendThreadMethod]): Post
the NSThreadDidStartNotification.
* Source/NSThread.m, Headers/gnustep/base/NSThread.h
([+registerCurrentThread]), ([+unregisterCurrentThread]): New
methods.
2000-11-10 Mirko Viviani <mirko.viviani@rccr.cremona.it>
* Source/NSBundle.m ([NSBundle +_addFrameworkFromClass:]): avoid crash

View file

@ -64,13 +64,57 @@ typedef enum
@end
/* Notification Strings. */
#ifndef NO_GNUSTEP
/*
* Don't use the following methods unless you really know what you are
* doing !
* The following methods are low-levelish and special.
* They are meant to make it possible to run GNUstep code in threads
* created in completely different environment, eg inside a JVM.
*
* If you use them, make sure you initialize the NSThread class inside
* (what you consider to be your) main thread, before registering any
* other thread. To initialize NSThread, simply call GSCurrentThread
* (). The main thread will not need to be registered.
*/
@interface NSThread (GNUstepRegister)
/*
* Register an external thread (created using your OS thread interface
* directly) to GNUstep. This means that it creates a NSThread object
* corresponding to the current thread, and sets things up so that you
* can run GNUstep code inside the thread. If the thread was not
* known to GNUstep, this methods registers it, and returns YES. If
* the thread was already known to GNUstep, this method does nothing
* and returns NO. */
+ (BOOL) registerCurrentThread;
/*
* Unregister the current thread from GNUstep. You must only
* unregister threads which have been register using + (BOOL)
* registerCurrentThread. This method is basically the same as
* `+exit', but does not exit the thread - just destroys all objects
* associated with the thread. Warning: using any GNUstep code after
* this method call is not safe.
*/
+ (void) unregisterCurrentThread;
@end
#endif
/*
* Notification Strings.
* NSBecomingMultiThreaded and NSThreadExiting are defined for strict
* OpenStep compatibility, the actual notification names are the more
* modern OPENSTEP/MacOS versions.
*/
GS_EXPORT NSString *NSWillBecomeMultiThreadedNotification;
#define NSBecomingMultiThreaded NSWillBecomeMultiThreadedNotification
GS_EXPORT NSString *NSThreadWillExitNotification;
#define NSThreadExiting NSThreadWillExitNotification
#ifndef NO_GNUSTEP
GS_EXPORT NSString *NSThreadDidStartNotification;
/*
* Get current thread and it's dictionary.
*/

View file

@ -6,6 +6,9 @@
Created: 1996
Rewritten by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
to add optimisations features for faster thread access.
Modified by: Nicola Pero <n.pero@mi.flashnet.it>
to add GNUstep extensions allowing to interact with threads created
by external libraries/code (eg, a Java Virtual Machine).
This file is part of the GNUstep Objective-C Library.
@ -32,6 +35,32 @@
#include <Foundation/NSString.h>
#include <Foundation/NSNotificationQueue.h>
#ifndef NO_GNUSTEP
/* We need to access these private vars in the objc runtime - because
the objc runtime's API is not enough powerful for the GNUstep
extensions we want to add. */
extern int __objc_is_multi_threaded;
extern objc_mutex_t __objc_runtime_mutex;
extern int __objc_runtime_threads_alive;
/* TODO: Submit patches to the objc runtime to add the following
two functions */
inline static void objc_thread_add ()
{
objc_mutex_lock(__objc_runtime_mutex);
__objc_is_multi_threaded = 1;
__objc_runtime_threads_alive++;
objc_mutex_unlock(__objc_runtime_mutex);
}
inline static void objc_thread_remove ()
{
objc_mutex_lock(__objc_runtime_mutex);
__objc_runtime_threads_alive--;
objc_mutex_unlock(__objc_runtime_mutex);
}
#endif
@interface NSThread (Private)
- (id) _initWithSelector: (SEL)s toTarget: (id)t withObject: (id)o;
- (void) _sendThreadMethod;
@ -330,6 +359,10 @@ gnustep_base_thread_callback()
- (void) _sendThreadMethod
{
#ifndef NO_GNUSTEP
NSNotification *n;
#endif
/*
* We are running in the new thread - so we store ourself in the thread
* dictionary and release ourself - thus, when the thread exits, we will
@ -337,6 +370,19 @@ gnustep_base_thread_callback()
*/
objc_thread_set_data(self);
_active = YES;
#ifndef NO_GNUSTEP
/*
* Let observers know a new thread is starting.
*/
n = [NSNotification alloc];
n = [n initWithName: NSThreadDidStartNotification
object: self
userInfo: nil];
[[NSNotificationCenter defaultCenter] postNotification: n];
RELEASE(n);
#endif
[_target performSelector: _selector withObject: _arg];
[NSThread exit];
}
@ -358,3 +404,67 @@ gnustep_base_thread_callback()
@end
@implementation NSThread (GNUstepRegister)
+ (BOOL) registerCurrentThread
{
NSThread *thread;
/*
* Do nothing and return NO if the thread is known to us.
*/
if ((NSThread*)objc_thread_get_data() != nil)
{
return NO;
}
/*
* Create the new thread object.
*/
thread = (NSThread*)NSAllocateObject (self, 0, NSDefaultMallocZone ());
thread = [thread _initWithSelector: NULL toTarget: nil withObject: nil];
objc_thread_set_data (thread);
((NSThread *)thread)->_active = YES;
/*
* Make sure the Objective-C runtime knows there is an additional thread.
*/
objc_thread_add ();
/*
* We post the notification after we register the thread.
*/
gnustep_base_thread_callback();
return YES;
}
+ (void) unregisterCurrentThread
{
NSThread *thread;
thread = GSCurrentThread();
if (thread->_active == YES)
{
/*
* Set the thread to be inactive to avoid any possibility of recursion.
*/
thread->_active = NO;
/*
* Release anything in our autorelease pools
*/
[NSAutoreleasePool _endThread];
/*
* destroy the thread object.
*/
DESTROY (thread);
objc_thread_set_data (NULL);
/*
* Make sure Objc runtime knows there is a thread less to manage
*/
objc_thread_remove ();
}
}
@end

View file

@ -50,6 +50,8 @@ NSString *NSConnectionDidInitializeNotification;
*/
NSString *NSWillBecomeMultiThreadedNotification;
NSString *NSThreadDidStartNotification;
NSString *NSThreadWillExitNotification;
@ -451,6 +453,8 @@ GSBuildStrings()
= [[SClass alloc] initWithCString: "NSThisDayDesignations"];
NSThousandsSeparator
= [[SClass alloc] initWithCString: "NSThousandsSeparator"];
NSThreadDidStartNotification
= [[SClass alloc] initWithCString: "NSThreadDidStartNotification"];
NSThreadWillExitNotification
= [[SClass alloc] initWithCString: "NSThreadWillExitNotification"];
NSTimeDateFormatString