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,16 +367,26 @@ 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)
{
NS_DURING
{
[GSPerformHolder class]; // Force initialization [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) if (nc == nil)
{ {
nc = [NSNotificationCenter defaultCenter]; nc = [NSNotificationCenter defaultCenter];
@ -384,6 +395,14 @@ gnustep_base_thread_callback()
object: nil object: nil
userInfo: nil]; userInfo: nil];
} }
NS_HANDLER
{
}
NS_ENDHANDLER
entered_multi_threaded_state = YES;
}
[gnustep_global_lock unlock];
}
} }