git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@14243 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-Macdonald 2002-08-07 15:30:03 +00:00
parent a702331098
commit 91b76f496f
6 changed files with 77 additions and 107 deletions

View file

@ -8,6 +8,11 @@
* Source/NSNotificationCenter.m: Modified posting to behave like the
MacOS-X implementation. Implement concrete subclass of
NSNotification.
* Source/NSUserDefaults.m: Try to make creation of new defaults
database an atomic operation.
* Source/NSObject.m: Remove dealloc notifications hack ... the
dealloc method can now safely be used to refrain from deallocating
objects, so I don't think the hack is needed any more.
2002-07-29 Adam Fedor <fedor@gnu.org>

View file

@ -292,17 +292,6 @@ GS_EXPORT NSRecursiveLock *gnustep_global_lock;
+ (void) enableDoubleReleaseCheck: (BOOL)enable;
- (id) read: (TypedStream*)aStream;
- (id) write: (TypedStream*)aStream;
/**
* If the 'deallocActivationsActive' flag is set, the _dealloc method will be
* called during the final release of an object, and the dealloc method will
* then be called only if _dealloc returns YES.
* You can override the _dealloc implementation to perform some action before
* an object is deallocated (or disable deallocation by returning NO).
* The default implementation simply returns YES.
*/
- (BOOL) deallocNotificationsActive;
- (void) setDeallocNotificationsActive: (BOOL)flag;
- (BOOL) _dealloc;
@end
#endif

View file

@ -274,6 +274,11 @@ add_to_queue(NSNotificationQueueList *queue, NSNotification *notification,
* NSNotificationQueue class implementation
*/
@interface NSNotificationQueue (Private)
- (void) _postNotification: (NSNotification*)notification
forModes: (NSArray*)modes;
@end
@implementation NSNotificationQueue
+ (NSNotificationQueue*) defaultQueue
@ -432,19 +437,6 @@ add_to_queue(NSNotificationQueueList *queue, NSNotification *notification,
}
}
- (void) postNotification: (NSNotification*)notification
forModes: (NSArray*)modes
{
NSString *mode = [[NSRunLoop currentRunLoop] currentMode];
// check to see if run loop is in a valid mode
if (mode == nil || modes == nil
|| [modes indexOfObject: mode] != NSNotFound)
{
[_center postNotification: notification];
}
}
- (void) enqueueNotification: (NSNotification*)notification
postingStyle: (NSPostingStyle)postingStyle
{
@ -468,7 +460,7 @@ add_to_queue(NSNotificationQueueList *queue, NSNotification *notification,
switch (postingStyle)
{
case NSPostNow:
[self postNotification: notification forModes: modes];
[self _postNotification: notification forModes: modes];
break;
case NSPostASAP:
add_to_queue(_asapQueue, notification, modes, _zone);
@ -481,6 +473,23 @@ add_to_queue(NSNotificationQueueList *queue, NSNotification *notification,
@end
@implementation NSNotificationQueue (Private)
- (void) _postNotification: (NSNotification*)notification
forModes: (NSArray*)modes
{
NSString *mode = [[NSRunLoop currentRunLoop] currentMode];
// check to see if run loop is in a valid mode
if (mode == nil || modes == nil
|| [modes indexOfObject: mode] != NSNotFound)
{
[_center postNotification: notification];
}
}
@end
/*
* The following code handles sending of queued notifications by
* NSRunLoop.
@ -500,7 +509,7 @@ static inline void notifyASAP(NSNotificationQueue *q)
NSArray *modes = item->modes;
remove_from_queue_no_release(list, item);
[q postNotification: notification forModes: modes];
[q _postNotification: notification forModes: modes];
RELEASE(notification);
RELEASE(modes);
NSZoneFree(((accessQueue)q)->_zone, item);
@ -535,7 +544,7 @@ static inline void notifyIdle(NSNotificationQueue *q)
NSArray *modes = item->modes;
remove_from_queue_no_release(list, item);
[q postNotification: notification forModes: modes];
[q _postNotification: notification forModes: modes];
RELEASE(notification);
RELEASE(modes);
NSZoneFree(((accessQueue)q)->_zone, item);

View file

@ -70,8 +70,6 @@ static Class NSConstantStringClass;
@class NSDataMalloc;
@class NSMutableDataMalloc;
static BOOL deallocNotifications = NO;
/*
* allocationLock is needed when running multi-threaded for retain/release
* to work reliably.
@ -836,7 +834,17 @@ static BOOL double_release_check_enabled = NO;
}
/**
* Deallocates the receiver by calling NSDeallocateObject()
* Deallocates the receiver by calling NSDeallocateObject() with self
* as the argument.<br />
* You should normally call the superclass implementation of this method
* when you override it in a subclass, or the memory occupied by your
* object will not be released.<br />
* If you have allocated the memory using a non-standard mechanism, you
* will not call the superclass (NSObject) implementation of the method
* as you will need to handle the deallocation specially.<br />
* In some circumstances, an object may wish to prevent itsself from
* being deallocated, it can do this simply be refraining from calling
* the superclass implementation.
*/
- (void) dealloc
{
@ -1343,18 +1351,14 @@ static BOOL double_release_check_enabled = NO;
}
/**
* Decrements the retain count for the receiver unless it is 1, in which
* case the dealloc method is called instead.<br />
* Decrements the retain count for the receiver if greater than zeron,
* otherwise calls the dealloc method instead.<br />
* The default implementation calls the NSDecrementExtraRefCountWasZero()
* function to test the extra reference count for the receiver (and
* decrement it if non-zero) - if the extra reference count is zero then
* the retain count is one, and the dealloc method is called.<br />
* In GNUstep, the [NSObject+enableDoubleReleaseCheck:] method may be used
* to turn on checking for ratain/release errors in this method.<br />
* GNUstep also supports deallocation notifications ... if this feature is
* turned on (See [NSObject-setDeallocNotificationsActive:]) then the
* [NSObject-_dealloc] method is called to notify the objct that it is
* about to be deallocated.
* to turn on checking for ratain/release errors in this method.
*/
- (oneway void) release
{
@ -1371,10 +1375,7 @@ static BOOL double_release_check_enabled = NO;
if (NSDecrementExtraRefCountWasZero(self))
{
if (deallocNotifications == NO || [self _dealloc] == YES)
{
[self dealloc];
}
[self dealloc];
}
#endif
}
@ -1756,26 +1757,6 @@ static BOOL double_release_check_enabled = NO;
[(id)self descriptionWithLocale: aLocale indent: level]];
}
/**
* Returns a flag to say whether dealloc notifications should be done.<br />
* See the -setDeallocNotificationsActive: method.
*/
- (BOOL) deallocNotificationsActive
{
return deallocNotifications;
}
/**
* Sets a flag to indicate whether dealloc notifications should be done.<br />
* If this flag is set, when an object is to be deallocated the -_dealloc
* method will be called first to notify the object that it is about to be
* deallocated.
*/
- (void) setDeallocNotificationsActive: (BOOL)flag
{
deallocNotifications = flag;
}
- (BOOL) _dealloc
{
return YES;

View file

@ -1502,7 +1502,7 @@ if (0) {
info = [self _getWatcher: data type: type forMode: mode];
if (info && info->receiver == (id)watcher)
if (info != nil && info->receiver == watcher)
{
/* Increment usage count for this watcher. */
info->count++;

View file

@ -1164,6 +1164,8 @@ static NSString *pathForUser(NSString *user)
NSFileManager *mgr = [NSFileManager defaultManager];
NSMutableDictionary *newDict;
NSDictionary *attr;
unsigned long desired;
unsigned long attributes;
[_lock lock];
@ -1217,11 +1219,17 @@ static NSString *pathForUser(NSString *user)
DESTROY(_dictionaryRep);
// Read the persistent data from the stored database
if (attr != nil)
if (attr == nil)
{
newDict = [[NSMutableDictionaryClass allocWithZone: [self zone]]
initWithCapacity: 1];
NSLog(@"Creating defaults database file %@", _defaultsDatabase);
[newDict writeToFile: _defaultsDatabase atomically: YES];
attr = [mgr fileAttributesAtPath: _defaultsDatabase
traverseLink: YES];
}
else
{
unsigned long desired;
unsigned long attributes;
newDict = [[NSMutableDictionaryClass allocWithZone: [self zone]]
initWithContentsOfFile: _defaultsDatabase];
if (newDict == nil)
@ -1230,53 +1238,31 @@ static NSString *pathForUser(NSString *user)
[_lock unlock];
return NO;
}
attributes = [attr filePosixPermissions];
// We enforce the permission mode 0600 on the defaults database
#if !(defined(S_IRUSR) && defined(S_IWUSR))
desired = 0600;
#else
desired = (S_IRUSR|S_IWUSR);
#endif
if (attributes != desired)
{
NSMutableDictionary *enforced_attributes;
NSNumber *permissions;
enforced_attributes = [NSMutableDictionary dictionaryWithDictionary:
[mgr fileAttributesAtPath: _defaultsDatabase traverseLink: YES]];
permissions = [NSNumber numberWithUnsignedLong: desired];
[enforced_attributes setObject: permissions
forKey: NSFilePosixPermissions];
[mgr changeFileAttributes: enforced_attributes
atPath: _defaultsDatabase];
}
}
else
{
unsigned long desired;
NSNumber *permissions;
// We enforce the permission mode 0600 on the defaults database
/*
* We enforce the permission mode 0600 on the defaults database
*/
attributes = [attr filePosixPermissions];
#if !(defined(S_IRUSR) && defined(S_IWUSR))
desired = 0600;
desired = 0600;
#else
desired = (S_IRUSR|S_IWUSR);
desired = (S_IRUSR|S_IWUSR);
#endif
if (attributes != desired)
{
NSMutableDictionary *enforced_attributes;
NSNumber *permissions;
enforced_attributes = [NSMutableDictionary dictionaryWithDictionary:
[mgr fileAttributesAtPath: _defaultsDatabase traverseLink: YES]];
permissions = [NSNumber numberWithUnsignedLong: desired];
attr = [NSDictionary dictionaryWithObjectsAndKeys:
NSUserName(), NSFileOwnerAccountName,
permissions, NSFilePosixPermissions,
nil];
NSLog(@"Creating defaults database file %@", _defaultsDatabase);
[mgr createFileAtPath: _defaultsDatabase
contents: nil
attributes: attr];
newDict = [[NSMutableDictionaryClass allocWithZone: [self zone]]
initWithCapacity: 1];
[newDict writeToFile: _defaultsDatabase atomically: YES];
[enforced_attributes setObject: permissions
forKey: NSFilePosixPermissions];
[mgr changeFileAttributes: enforced_attributes
atPath: _defaultsDatabase];
}
if (_changedDomains)