aboutsummaryrefslogtreecommitdiffhomepage
path: root/objectivec/GPBMessage.m
diff options
context:
space:
mode:
authorGravatar Thomas Van Lenten <thomasvl@google.com>2017-03-29 14:07:07 -0400
committerGravatar GitHub <noreply@github.com>2017-03-29 14:07:07 -0400
commit258406b88f2d0ea95b90ac778f245baf9a9cea95 (patch)
treea8e22004c8673f935825a40606a4091e9293175a /objectivec/GPBMessage.m
parentba3fa41ba86cd87f1947b9e66e450b9dc39e85a6 (diff)
parent130c166697cc7df082197a10936dd9554c3e4083 (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.m19
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];