Thread safety fixes

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@6623 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
richard 2000-05-27 05:05:10 +00:00
parent 9f1d5b4c80
commit 1ea145548c
2 changed files with 33 additions and 13 deletions

View file

@ -1,3 +1,8 @@
2000-05-27 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSBundle.m: Protect all use of map tables of bundles
using lock - should make class thread-safe.
2000-05-25 Adam Fedor <fedor@gnu.org> 2000-05-25 Adam Fedor <fedor@gnu.org>
* Headers/gnustep/base/GSIArray.h: remove config.h * Headers/gnustep/base/GSIArray.h: remove config.h

View file

@ -307,6 +307,7 @@ _bundle_load_callback(Class theClass, Category *theCategory)
void *key; void *key;
NSBundle *bundle; NSBundle *bundle;
[load_lock lock];
enumerate = NSEnumerateMapTable(_bundles); enumerate = NSEnumerateMapTable(_bundles);
while (NSNextMapEnumeratorPair(&enumerate, &key, (void **)&bundle)) while (NSNextMapEnumeratorPair(&enumerate, &key, (void **)&bundle))
{ {
@ -316,6 +317,7 @@ _bundle_load_callback(Class theClass, Category *theCategory)
[array addObject: bundle]; [array addObject: bundle];
} }
} }
[load_lock unlock];
return array; return array;
} }
@ -379,6 +381,7 @@ _bundle_load_callback(Class theClass, Category *theCategory)
if (!aClass) if (!aClass)
return nil; return nil;
[load_lock lock];
bundle = nil; bundle = nil;
enumerate = NSEnumerateMapTable(_bundles); enumerate = NSEnumerateMapTable(_bundles);
while (NSNextMapEnumeratorPair(&enumerate, &key, (void **)&bundle)) while (NSNextMapEnumeratorPair(&enumerate, &key, (void **)&bundle))
@ -389,6 +392,7 @@ _bundle_load_callback(Class theClass, Category *theCategory)
break; break;
bundle = nil; bundle = nil;
} }
[load_lock unlock];
if (!bundle) if (!bundle)
{ {
/* Is it in the main bundle? */ /* Is it in the main bundle? */
@ -422,13 +426,16 @@ _bundle_load_callback(Class theClass, Category *theCategory)
} }
/* Check if we were already initialized for this directory */ /* Check if we were already initialized for this directory */
[load_lock lock];
if (_bundles) if (_bundles)
{ {
NSBundle* bundle = (NSBundle *)NSMapGet(_bundles, path); NSBundle* bundle = (NSBundle *)NSMapGet(_bundles, path);
if (bundle) if (bundle)
{ {
RETAIN(bundle); /* retain - look as if we were alloc'ed */
[load_lock unlock];
[self dealloc]; [self dealloc];
return RETAIN(bundle); /* retain - look as if we were alloc'ed */ return bundle;
} }
} }
if (_releasedBundles) if (_releasedBundles)
@ -438,18 +445,26 @@ _bundle_load_callback(Class theClass, Category *theCategory)
{ {
NSMapInsert(_bundles, path, loaded); NSMapInsert(_bundles, path, loaded);
NSMapRemove(_releasedBundles, path); NSMapRemove(_releasedBundles, path);
RETAIN(loaded); /* retain - look as if we were alloc'ed */
[load_lock unlock];
[self dealloc]; [self dealloc];
return RETAIN(loaded); /* retain - look as if we were alloc'ed */ return loaded;
} }
} }
[load_lock unlock];
if (stat([path cString], &statbuf) != 0) if (stat([path cString], &statbuf) != 0)
{ {
NSDebugMLLog(@"NSBundle", @"Could not access path %s for bundle", [path cString]); NSDebugMLLog(@"NSBundle", @"Could not access path %@ for bundle", path);
//[self dealloc]; //[self dealloc];
//return nil; //return nil;
} }
_path = [path copy];
_bundleType = (unsigned int)NSBUNDLE_BUNDLE;
if (self == _mainBundle)
_bundleType = (unsigned int)NSBUNDLE_APPLICATION;
[load_lock lock]; [load_lock lock];
if (!_bundles) if (!_bundles)
{ {
@ -458,14 +473,9 @@ _bundle_load_callback(Class theClass, Category *theCategory)
_releasedBundles = NSCreateMapTable(NSObjectMapKeyCallBacks, _releasedBundles = NSCreateMapTable(NSObjectMapKeyCallBacks,
NSNonOwnedPointerMapValueCallBacks, 0); NSNonOwnedPointerMapValueCallBacks, 0);
} }
NSMapInsert(_bundles, _path, self);
[load_lock unlock]; [load_lock unlock];
_path = [path copy];
_bundleType = (unsigned int)NSBUNDLE_BUNDLE;
if (self == _mainBundle)
_bundleType = (unsigned int)NSBUNDLE_APPLICATION;
NSMapInsert(_bundles, _path, self);
return self; return self;
} }
@ -479,15 +489,18 @@ _bundle_load_callback(Class theClass, Category *theCategory)
{ {
if ([self retainCount] == 1) if ([self retainCount] == 1)
{ {
[load_lock lock];
if (self == NSMapGet(_releasedBundles, _path)) if (self == NSMapGet(_releasedBundles, _path))
{ {
[load_lock unlock];
[NSException raise: NSGenericException [NSException raise: NSGenericException
format: @"Bundle for path %@ released too many times", _path]; format: @"Bundle for path %@ released too many times", _path];
} }
NSMapRemove(_bundles, _path); NSMapRemove(_bundles, _path);
NSMapInsert(_releasedBundles, _path, self); NSMapInsert(_releasedBundles, _path, self);
return; [load_lock unlock];
return;
} }
} }
[super release]; [super release];
@ -495,9 +508,11 @@ _bundle_load_callback(Class theClass, Category *theCategory)
- (void) dealloc - (void) dealloc
{ {
if (_path) if (_path != nil)
{ {
[load_lock lock];
NSMapRemove(_bundles, _path); NSMapRemove(_bundles, _path);
[load_lock unlock];
RELEASE(_path); RELEASE(_path);
} }
TEST_RELEASE(_bundleClasses); TEST_RELEASE(_bundleClasses);