Thread safety fix ... ensure notifications are sent before we become

multithrteaded.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@17757 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
CaS 2003-09-30 18:19:03 +00:00
parent 88285c3596
commit 5401a03dd3
2 changed files with 41 additions and 12 deletions

View file

@ -1,3 +1,13 @@
2003-09-30 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSThread.m: Protect the function handling notification
of the process becoming multi-threaded with a recursive lock.
This protection ensures that there is no race condition where
two threads can start using GNUstep simultaneously and both
end up sending out notifications etc. Not a problem in normal
ObjC applications, but a possibility where other non-gnustep
code starts multiple threads which want to access gnustep.
2003-09-30 Derek Zhou <dzhou@chrontel.com> 2003-09-30 Derek Zhou <dzhou@chrontel.com>
* Source/NSCharacterSet.m: patch to ensure lock is created as * Source/NSCharacterSet.m: patch to ensure lock is created as

View file

@ -39,6 +39,7 @@
#include <time.h> #include <time.h>
#endif #endif
#include "Foundation/NSException.h"
#include "Foundation/NSThread.h" #include "Foundation/NSThread.h"
#include "Foundation/NSLock.h" #include "Foundation/NSLock.h"
#include "Foundation/NSString.h" #include "Foundation/NSString.h"
@ -366,23 +367,41 @@ static void
gnustep_base_thread_callback() gnustep_base_thread_callback()
{ {
/* /*
* Post a notification if this is the first new thread to be created. * Protect this function with locking ... to avoid any possibility
* Won't work properly if threads are not all created by this class, * of multiple threads registering with the system simultaneously,
* but it's better than nothing. * and so that all NSWillBecomeMultiThreadedNotifications are sent
* out before any second thread can interfere with anything.
*/ */
if (entered_multi_threaded_state == NO) if (entered_multi_threaded_state == NO)
{ {
entered_multi_threaded_state = YES; [gnustep_global_lock lock];
if (entered_multi_threaded_state == NO)
[GSPerformHolder class]; // Force initialization
if (nc == nil)
{ {
nc = [NSNotificationCenter defaultCenter]; NS_DURING
{
[GSPerformHolder class]; // Force initialization
/*
* 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, but it's better than nothing.
*/
if (nc == nil)
{
nc = [NSNotificationCenter defaultCenter];
}
[nc postNotificationName: NSWillBecomeMultiThreadedNotification
object: nil
userInfo: nil];
}
NS_HANDLER
{
}
NS_ENDHANDLER
entered_multi_threaded_state = YES;
} }
[nc postNotificationName: NSWillBecomeMultiThreadedNotification [gnustep_global_lock unlock];
object: nil
userInfo: nil];
} }
} }