Skip to content

Instantly share code, notes, and snippets.

Forked from boredzo/Makefile
Last active Sep 23, 2016
What would you like to do?
dispatch_once is not reentrant. Use a NSReentrantLock if you want reentrancy.
#import <Foundation/Foundation.h>
static NSRecursiveLock *_lock = nil;
// constructor = run before main. used = emit code even if the function is not referenced.
// See
static void runBeforeMain(void) __attribute__ ((constructor, used));
static void runBeforeMain(void) {
_lock = [NSRecursiveLock new];
static void test(void)
static NSUInteger count = 0;
NSLog(@"iteration #%lu", ++count);
// YES = deadlock after a reentrant call using dispatch_once
// NO = allow reentrant calls using NSRecursiveLock
BOOL deadlock = YES;
if (deadlock){
static dispatch_once_t token;
dispatch_once(&token, ^{
} else {
[_lock lock];
[_lock unlock];
int main(int argc, char **argv) {
@autoreleasepool {
CFLAGS+=-std=c99 -g
LDFLAGS+=-framework Foundation
dispatch_once_reentrancy_test: dispatch_once_reentrancy_test.o
Copy link

janodev commented Feb 8, 2013

dispatch_once is a barrier: it blocks other threads until it is done executing. However, it is not reentrant: it is not safe to call it again from the same thread before the previous invocation is done executing.

Reentrant calls with dispatch_once cause a deadlock. If you want a lock with reentrancy use NSRecursiveLock.

Note that dispatch_once is popular because it is faster than @synchronized to run a task just once (eg: initialize a singleton). But this is not true for all uses: @synchronized is faster than dispatch_once to execute repeated checks for race conditions (eg: atomic properties).

Copy link

lemonkey commented Sep 23, 2016

Does this address the issue with using @synchronized(self) within a singleton while code elsewhere could also being using @synchronized(singleton_instance), causing a dead lock?

While dispatch_once doesn't have this problem, like you mention it is not reentrant.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment