diff options
author | Thomas Van Lenten <thomasvl@google.com> | 2015-12-17 14:35:44 -0500 |
---|---|---|
committer | Thomas Van Lenten <thomasvl@google.com> | 2015-12-17 16:05:50 -0500 |
commit | d6590d653415c0bfacf97e7f768dd3c994cb8d26 (patch) | |
tree | 8c0f6f98eb867d520e95d30d32a6d0e4fe55906c /objectivec/GPBMessage.m | |
parent | afbc89a263d57bb2e36ce5f07b979c739bb2e8cd (diff) | |
download | protobuf-d6590d653415c0bfacf97e7f768dd3c994cb8d26.tar.gz protobuf-d6590d653415c0bfacf97e7f768dd3c994cb8d26.tar.bz2 protobuf-d6590d653415c0bfacf97e7f768dd3c994cb8d26.zip |
Drop all use of OSSpinLock
Apple engineers have pointed out that OSSpinLocks are vulnerable to live locking
on iOS in cases of priority inversion:
. http://mjtsai.com/blog/2015/12/16/osspinlock-is-unsafe/
. https://lists.swift.org/pipermail/swift-dev/Week-of-Mon-20151214/000372.html
- Use a dispatch_semaphore_t within the extension registry.
- Use a dispatch_semaphore_t for protecting autocreation within messages.
- Drop the custom/internal GPBString class since we don't have really good
numbers to judge the locking replacements and it isn't required. We can
always bring it back with real data in the future.
Diffstat (limited to 'objectivec/GPBMessage.m')
-rw-r--r-- | objectivec/GPBMessage.m | 14 |
1 files changed, 7 insertions, 7 deletions
diff --git a/objectivec/GPBMessage.m b/objectivec/GPBMessage.m index d9080c3f..208cfe4e 100644 --- a/objectivec/GPBMessage.m +++ b/objectivec/GPBMessage.m @@ -568,13 +568,13 @@ static id GetArrayIvarWithField(GPBMessage *self, GPBFieldDescriptor *field) { id array = GPBGetObjectIvarWithFieldNoAutocreate(self, field); if (!array) { // Check again after getting the lock. - OSSpinLockLock(&self->readOnlyMutex_); + dispatch_semaphore_wait(self->readOnlySemaphore_, DISPATCH_TIME_FOREVER); array = GPBGetObjectIvarWithFieldNoAutocreate(self, field); if (!array) { array = CreateArrayForField(field, self); GPBSetAutocreatedRetainedObjectIvarWithField(self, field, array); } - OSSpinLockUnlock(&self->readOnlyMutex_); + dispatch_semaphore_signal(self->readOnlySemaphore_); } return array; } @@ -598,13 +598,13 @@ static id GetMapIvarWithField(GPBMessage *self, GPBFieldDescriptor *field) { id dict = GPBGetObjectIvarWithFieldNoAutocreate(self, field); if (!dict) { // Check again after getting the lock. - OSSpinLockLock(&self->readOnlyMutex_); + dispatch_semaphore_wait(self->readOnlySemaphore_, DISPATCH_TIME_FOREVER); dict = GPBGetObjectIvarWithFieldNoAutocreate(self, field); if (!dict) { dict = CreateMapForField(field, self); GPBSetAutocreatedRetainedObjectIvarWithField(self, field, dict); } - OSSpinLockUnlock(&self->readOnlyMutex_); + dispatch_semaphore_signal(self->readOnlySemaphore_); } return dict; } @@ -810,7 +810,7 @@ static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self) { messageStorage_ = (GPBMessage_StoragePtr)( ((uint8_t *)self) + class_getInstanceSize([self class])); - readOnlyMutex_ = OS_SPINLOCK_INIT; + readOnlySemaphore_ = dispatch_semaphore_create(1); } return self; @@ -1723,7 +1723,7 @@ static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self) { } // Check for an autocreated value. - OSSpinLockLock(&readOnlyMutex_); + dispatch_semaphore_wait(readOnlySemaphore_, DISPATCH_TIME_FOREVER); value = [autocreatedExtensionMap_ objectForKey:extension]; if (!value) { // Auto create the message extensions to match normal fields. @@ -1740,7 +1740,7 @@ static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self) { [value release]; } - OSSpinLockUnlock(&readOnlyMutex_); + dispatch_semaphore_signal(readOnlySemaphore_); return value; } |