diff options
author | Mike Ash <mike@mikeash.com> | 2014-01-17 23:51:12 +0400 |
---|---|---|
committer | Mike Ash <mike@mikeash.com> | 2014-01-17 23:51:12 +0400 |
commit | 6fbd05f6c396c0984e77ac8080684a5ec38b6256 (patch) | |
tree | 47d36e0f65a7090f1bf7a6610ad498663d6a55aa | |
parent | 395f7b7a9800fbe51f3a31ffb275481b5939999b (diff) |
Add a deadlock check to -[FMDatabaseQueue inDatabase:]
-rw-r--r-- | src/FMDatabaseQueue.m | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/src/FMDatabaseQueue.m b/src/FMDatabaseQueue.m index 40e9658..89d0f51 100644 --- a/src/FMDatabaseQueue.m +++ b/src/FMDatabaseQueue.m @@ -16,6 +16,13 @@ something in dispatch_sync */ + +/** + * A key used to associate the FMDatabaseQueue object with the dispatch_queue_t it uses. + * This in turn is used for deadlock detection by seeing if inDatabase: is called on + * the queue's dispatch queue, which should not happen and causes a deadlock. + */ +static const void * const kDispatchQueueSpecificKey = &kDispatchQueueSpecificKey; @implementation FMDatabaseQueue @@ -67,6 +74,7 @@ _path = FMDBReturnRetained(aPath); _queue = dispatch_queue_create([[NSString stringWithFormat:@"fmdb.%@", self] UTF8String], NULL); + dispatch_queue_set_specific(_queue, kDispatchQueueSpecificKey, (__bridge void *)self, NULL); _openFlags = openFlags; } @@ -129,6 +137,11 @@ } - (void)inDatabase:(void (^)(FMDatabase *db))block { + /* Get the currently executing queue (which should probably be nil, but in theory could be another DB queue + * and then check it against self to make sure we're not about to deadlock. */ + FMDatabaseQueue *currentSyncQueue = (__bridge id)dispatch_get_specific(kDispatchQueueSpecificKey); + assert(currentSyncQueue != self && "inDatabase: was called reentrantly on the same queue, which would lead to a deadlock"); + FMDBRetain(self); dispatch_sync(_queue, ^() { |