Yapdatabase can be accidently deadlocked by executing a synchronous read block within a synchronous read block, or a read block within a synchronous read/write block, or a read/write block within a synchronous read/write block.
As an example readWithBlock currently looks like this:
- (void)readWithBlock:(void (^)(YapDatabaseReadTransaction *))block
{
...
dispatch_sync(connectionQueue, ^{ @autoreleasepool {
/// run the block
}});
}
Perhaps it could look like this:
- (void)readWithBlock:(void (^)(YapDatabaseReadTransaction *))block
{
...
if (dispatch_get_current_queue() == connectionQueue) {
/// run the block
return;
}
dispatch_sync(connectionQueue, ^{ @autoreleasepool {
/// run the block
}});
}
I haven't fully thought this through to see if there are any downsides.
For example I haven't thought about how yapdatabase would prevent this type of logic from incorrectly promoting a read block to a read write block.
Perhaps as an alternative yapdatabase should log that the deadlock is about to happen.
Yapdatabase can be accidently deadlocked by executing a synchronous read block within a synchronous read block, or a read block within a synchronous read/write block, or a read/write block within a synchronous read/write block.
As an example readWithBlock currently looks like this:
Perhaps it could look like this:
I haven't fully thought this through to see if there are any downsides.
For example I haven't thought about how yapdatabase would prevent this type of logic from incorrectly promoting a read block to a read write block.
Perhaps as an alternative yapdatabase should log that the deadlock is about to happen.