diff options
author | 2017-03-29 14:07:07 -0400 | |
---|---|---|
committer | 2017-03-29 14:07:07 -0400 | |
commit | 258406b88f2d0ea95b90ac778f245baf9a9cea95 (patch) | |
tree | a8e22004c8673f935825a40606a4091e9293175a /objectivec/GPBMessage.m | |
parent | ba3fa41ba86cd87f1947b9e66e450b9dc39e85a6 (diff) | |
parent | 130c166697cc7df082197a10936dd9554c3e4083 (diff) |
Merge pull request #2919 from thomasvl/drop_dispatch
Remove the use of dispatch_once that is heap backed.
Diffstat (limited to 'objectivec/GPBMessage.m')
-rw-r--r-- | objectivec/GPBMessage.m | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/objectivec/GPBMessage.m b/objectivec/GPBMessage.m index 58a10fdb..78935b19 100644 --- a/objectivec/GPBMessage.m +++ b/objectivec/GPBMessage.m @@ -738,6 +738,25 @@ void GPBClearMessageAutocreator(GPBMessage *self) { self->autocreatorExtension_ = nil; } +// Call this before using the readOnlySemaphore_. This ensures it is created only once. +void GPBPrepareReadOnlySemaphore(GPBMessage *self) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdirect-ivar-access" +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + + // Create the semaphore on demand (rather than init) as developers might not cause them + // to be needed, and the heap usage can add up. The atomic swap is used to avoid needing + // another lock around creating it. + if (self->readOnlySemaphore_ == nil) { + dispatch_semaphore_t worker = dispatch_semaphore_create(1); + if (!OSAtomicCompareAndSwapPtrBarrier(NULL, worker, (void * volatile *)&(self->readOnlySemaphore_))) { + dispatch_release(worker); + } + } + +#pragma clang diagnostic pop +} + static GPBUnknownFieldSet *GetOrMakeUnknownFields(GPBMessage *self) { if (!self->unknownFields_) { self->unknownFields_ = [[GPBUnknownFieldSet alloc] init]; |