Hi all,
The code below demonstrates the problem I'm seeing with gnustep-base
1.13.0 on i386/Linux, where NSThread
+detachNewThreadSelector:toTarget:withObject: is not consistently
executing the method indicated. I'm trying to choose my words
carefully here, because it *does* create a new LWP. In fact, if I
set a breakpoint at the [NSThread ...] line, I can step through
NSThread.m and see that objc_thread_dispatch returns non-NULL[*].
However, the global variable x never gets set and none of the NSLog()
lines in the -doStuff method appear. I'm not so good with debugging
multiple-threaded apps but if I step past objc_thread_detach then
look at the threads display in ddd, I only see one thread, although I
do get a notification of a new LWP from the debugger.
It looks like it might be racy, because if I step past the section
(lines 551-555 here, I'm on base 1.13.0) in NSThread.m:
if (objc_thread_detach(@selector(__sendThreadMethod),thread,nil)
== NULL)
{
[NSException raise: NSInternalConsistencyException
format: @"Unable to detach thread (unknown error)"];
} // <--step to here
}
and continue from there, I do get the change in x and the NSLog()
messages as expected. Similarly if I execute the objc_thread_detach
() function myself in the debugger by assigning its return value to a
convenience variable, I get the expected result. But never when just
running the code, debug=yes or not. The same program does what I
expect - i.e. prints out all the NSLog()s and sets x to 3 - with the
Apple Foundation.
[*] I can't step _into_ it, I guess because my objc runtime wasn't
built with debugging symbols.
Here's the source.
--8<--
#include <Foundation/Foundation.h>
NSLock *lock;
int x=0;
@interface AnObject:NSObject
{
}
- (void)doStuff;
@end
@implementation AnObject
- (void)doStuff
{
id localPool=[[NSAutoreleasePool alloc] init];
NSLog(@"Here we go, acquiring lock...");
[lock lock];
x=3;
NSLog(@"Relinquish lock...");
[lock unlock];
[localPool release];
}
@end
int
main(int argc, const char *argv[])
{
id pool = [[NSAutoreleasePool alloc] init];
AnObject *obj=[[AnObject alloc] init];
lock=[[NSLock alloc] init];
// Your code here...
NSLog(@"Spawning the thread...");
[NSThread detachNewThreadSelector:@selector(doStuff) toTarget:obj
withObject:nil];
NSLog(@"It's been launched.");
// The end...
while([lock tryLock]==NO);
NSLog(@"Teardown: x=%d",x);
[obj release];
[lock release];
[pool release];
return 0;
}
--8<--
Cheers,
Graham.
--
Graham J Lee
http://www.thaesofereode.info/
_______________________________________________
Bug-gnustep mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/bug-gnustep