mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 09:04:13 +00:00
Thread fix - retain target and argument
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@4587 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
b1eec7c6f3
commit
15518a7468
2 changed files with 58 additions and 1 deletions
|
@ -1,3 +1,8 @@
|
|||
Wed Jul 14 17:36:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
|
||||
* Source/NSThread.m: Make sure that a thread retains the target object
|
||||
and argument of the method with which it is detached.
|
||||
|
||||
Wed Jul 14 16:58:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
|
||||
* Source/NSAttributedString.m: Fixed ([allocWithZone:]) so that
|
||||
|
|
|
@ -32,6 +32,53 @@
|
|||
#include <Foundation/NSString.h>
|
||||
#include <Foundation/NSNotificationQueue.h>
|
||||
|
||||
/*
|
||||
* A class to defer the use of the real thread method until we have
|
||||
* an autlorelease pool so that target and arg can be safely released
|
||||
* once they are no longer needed.
|
||||
*/
|
||||
@interface GSThreadLauncher : NSObject
|
||||
{
|
||||
id target;
|
||||
id arg;
|
||||
SEL sel;
|
||||
}
|
||||
+ (GSThreadLauncher*) newWithTarget: (id)t selector: (SEL)s arg: (id)a;
|
||||
- (void) sendThreadMethod;
|
||||
@end
|
||||
|
||||
@implementation GSThreadLauncher
|
||||
+ (GSThreadLauncher*) newWithTarget: (id)t selector: (SEL)s arg: (id)a
|
||||
{
|
||||
GSThreadLauncher *l;
|
||||
|
||||
l = (GSThreadLauncher*)NSAllocateObject(self, 0, NSDefaultMallocZone());
|
||||
l->target = RETAIN(t);
|
||||
l->arg = RETAIN(a);
|
||||
l->sel = s;
|
||||
return l;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
RELEASE(target);
|
||||
RELEASE(arg);
|
||||
NSDeallocateObject(self);
|
||||
}
|
||||
|
||||
- (void) sendThreadMethod
|
||||
{
|
||||
/*
|
||||
* We are running in the new thread - so an autorelease puts us in the
|
||||
* pool for the thread. If the thread object calls [NSThread exit] the
|
||||
* pool will be released, otherwise, we call it ourself.
|
||||
*/
|
||||
AUTORELEASE(self);
|
||||
[target performSelector: sel withObject: arg];
|
||||
[NSThread exit];
|
||||
}
|
||||
@end
|
||||
|
||||
// Class variables
|
||||
|
||||
/* Flag indicating whether the objc runtime ever went multi-threaded. */
|
||||
|
@ -144,6 +191,7 @@ void gnustep_base_thread_callback()
|
|||
toTarget: (id)aTarget
|
||||
withObject: (id)anArgument
|
||||
{
|
||||
GSThreadLauncher *launcher;
|
||||
/*
|
||||
* Make sure the notification is posted BEFORE the new thread starts.
|
||||
*/
|
||||
|
@ -151,7 +199,11 @@ void gnustep_base_thread_callback()
|
|||
/*
|
||||
* Have the runtime detach the thread
|
||||
*/
|
||||
if (objc_thread_detach (aSelector, aTarget, anArgument) == NULL)
|
||||
launcher = [GSThreadLauncher newWithTarget: aTarget
|
||||
selector: aSelector
|
||||
arg: anArgument];
|
||||
|
||||
if (objc_thread_detach(@selector(sendThreadMethod), launcher, nil) == NULL)
|
||||
{
|
||||
/* This should probably be an exception */
|
||||
NSLog(@"Unable to detach thread (unknown error)");
|
||||
|
|
Loading…
Reference in a new issue