Skip to content

Commit

Permalink
process monitor crashes (#3010)
Browse files Browse the repository at this point in the history
* Simplify locks with @synchronized

* Use threadsafe dicts for data and meta
  • Loading branch information
n8henrie authored Oct 5, 2024
1 parent f4f679f commit 133f01e
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 66 deletions.
4 changes: 2 additions & 2 deletions Quicksilver/Code-QuickStepCore/QSObject.m
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ + (void)interfaceChanged {
- (id)init {
if (self = [super init]) {

data = [NSMutableDictionary dictionaryWithCapacity:0];
meta = [NSMutableDictionary dictionaryWithCapacity:0];
data = [QSThreadSafeMutableDictionary dictionaryWithCapacity:0];
meta = [QSThreadSafeMutableDictionary dictionaryWithCapacity:0];
cache = [QSThreadSafeMutableDictionary dictionaryWithCapacity:0];
name = nil;
label = nil;
Expand Down
126 changes: 62 additions & 64 deletions Quicksilver/Code-QuickStepFoundation/QSThreadSafeMutableDictionary.m
Original file line number Diff line number Diff line change
Expand Up @@ -28,129 +28,127 @@

#import "QSThreadSafeMutableDictionary.h"

#import <libkern/OSAtomic.h>

#define LOCKED(...) OSSpinLockLock(&_lock); \
__VA_ARGS__; \
OSSpinLockUnlock(&_lock);
//#import <libkern/OSAtomic.h>

@implementation QSThreadSafeMutableDictionary {
OSSpinLock _lock;
NSMutableDictionary *_dictionary; // Class Cluster!
NSMutableDictionary *_dictionary;
}

///////////////////////////////////////////////////////////////////////////////////////////
#pragma mark - NSObject

- (id)init {
if ((self = [super init])) {
_dictionary = [[NSMutableDictionary alloc] init];
_lock = OS_SPINLOCK_INIT;
}
return self;
if ((self = [super init])) {
_dictionary = [[NSMutableDictionary alloc] init];
}
return self;
}

- (id)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys {
if ((self = [self initWithCapacity:objects.count])) {
[objects enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
_dictionary[keys[idx]] = obj;
}];
}
return self;
if ((self = [self initWithCapacity:objects.count])) {
[objects enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
_dictionary[keys[idx]] = obj;
}];
}
return self;
}

- (id)initWithCapacity:(NSUInteger)capacity {
if ((self = [super init])) {
_dictionary = [[NSMutableDictionary alloc] initWithCapacity:capacity];
_lock = OS_SPINLOCK_INIT;
}
return self;
if ((self = [super init])) {
_dictionary = [[NSMutableDictionary alloc] initWithCapacity:capacity];
}
return self;
}

///////////////////////////////////////////////////////////////////////////////////////////
#pragma mark - NSMutableDictionary

- (void)setObject:(id)anObject forKey:(id<NSCopying>)aKey {
LOCKED(_dictionary[aKey] = anObject)
@synchronized(_dictionary) { _dictionary[aKey] = anObject; }
}

- (void)addEntriesFromDictionary:(NSDictionary *)otherDictionary {
LOCKED([_dictionary addEntriesFromDictionary:otherDictionary]);
@synchronized(_dictionary) { [_dictionary addEntriesFromDictionary:otherDictionary]; };
}

- (void)setDictionary:(NSDictionary *)otherDictionary {
LOCKED([_dictionary setDictionary:otherDictionary]);
@synchronized(_dictionary) { [_dictionary setDictionary:otherDictionary]; };
}

- (void)removeObjectForKey:(id)aKey {
LOCKED([_dictionary removeObjectForKey:aKey])
@synchronized(_dictionary) { [_dictionary removeObjectForKey:aKey]; }
}

- (void)removeAllObjects {
LOCKED([_dictionary removeAllObjects]);
@synchronized(_dictionary) { [_dictionary removeAllObjects]; };
}

- (NSUInteger)count {
LOCKED(NSUInteger count = _dictionary.count)
return count;
@synchronized(_dictionary) {
NSUInteger count = _dictionary.count;
return count;}
}

- (NSArray *)allKeys {
LOCKED(NSArray *allKeys = _dictionary.allKeys)
return allKeys;
@synchronized(_dictionary) {
NSArray *allKeys = _dictionary.allKeys;
return allKeys;
}
}

- (NSArray *)allValues {
LOCKED(NSArray *allValues = _dictionary.allValues)
return allValues;
@synchronized(_dictionary) {
NSArray *allValues = _dictionary.allValues;
return allValues;
}
}

- (id)objectForKey:(id)aKey {
LOCKED(id obj = _dictionary[aKey])
return obj;
@synchronized(_dictionary) {
id obj = _dictionary[aKey];
return obj;
}
}

- (NSEnumerator *)keyEnumerator {
LOCKED(NSEnumerator *keyEnumerator = [_dictionary keyEnumerator])
return keyEnumerator;
@synchronized(_dictionary) {
NSEnumerator *keyEnumerator = [_dictionary keyEnumerator];
return keyEnumerator;
}
}

- (id)copyWithZone:(NSZone *)zone {
return [self mutableCopyWithZone:zone];
return [self mutableCopyWithZone:zone];
}

- (id)mutableCopyWithZone:(NSZone *)zone {
LOCKED(id copiedDictionary = [[self.class allocWithZone:zone] initWithDictionary:_dictionary])
return copiedDictionary;
@synchronized(_dictionary) {
id copiedDictionary = [[self.class allocWithZone:zone] initWithDictionary:_dictionary];
return copiedDictionary;
}
}

- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state
objects:(id __unsafe_unretained [])stackbuf
count:(NSUInteger)len {
LOCKED(NSUInteger count = [[_dictionary copy] countByEnumeratingWithState:state objects:stackbuf count:len]);
return count;
}

- (void)performLockedWithDictionary:(void (^)(NSDictionary *dictionary))block {
if (block) {
LOCKED(block(_dictionary));
}
objects:(id __unsafe_unretained [])stackbuf
count:(NSUInteger)len {
@synchronized(_dictionary) {
NSUInteger count = [[_dictionary copy] countByEnumeratingWithState:state objects:stackbuf count:len];
return count;
};
}

- (BOOL)isEqual:(id)object {
if (object == self) return YES;

if ([object isKindOfClass:QSThreadSafeMutableDictionary.class]) {
QSThreadSafeMutableDictionary *other = object;
__block BOOL isEqual = NO;
[other performLockedWithDictionary:^(NSDictionary *dictionary) {
[self performLockedWithDictionary:^(NSDictionary *otherDictionary) {
isEqual = [dictionary isEqual:otherDictionary];
}];
}];
return isEqual;
}
return NO;
if (object == self) return YES;

if ([object isKindOfClass:QSThreadSafeMutableDictionary.class]) {
QSThreadSafeMutableDictionary *other = object;
@synchronized (_dictionary) {
@synchronized (other) {
return [_dictionary isEqual:other];
}
}
}
return NO;
}

@end

0 comments on commit 133f01e

Please sign in to comment.