bug-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Thread (usually) not doing what I'd expect


From: Graham J Lee
Subject: Thread (usually) not doing what I'd expect
Date: Tue, 7 Nov 2006 14:29:06 +0000

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/






reply via email to

[Prev in Thread] Current Thread [Next in Thread]