diff options
author | August "Gus" Mueller <gus@flyingmeat.com> | 2014-01-18 00:29:40 +0400 |
---|---|---|
committer | August "Gus" Mueller <gus@flyingmeat.com> | 2014-01-18 00:29:40 +0400 |
commit | 018a7b81dd8b63d2c766e7482db8779599b754b3 (patch) | |
tree | 2a3d20d80edbbb11e67a1b967edae40a57d6b014 | |
parent | 75b5dddc87dbc39f36c6071cb31956a9bdc51bdb (diff) | |
parent | 6fbd05f6c396c0984e77ac8080684a5ec38b6256 (diff) |
Merge pull request #224 from mikeash/master
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, ^() { |