I changed my code from:properties = self.propertiesToSave;To something like this ensuring I'm always accessing the database on the same thread:dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{properties = self.propertiesToSave;});
2014-04-01 14:05:01.745 XXXXApp[78999:90b] *** Assertion failure in -[CBL_FMDatabase beginUse], /Users/couchbase/jenkins/workspace/build_cblite_ios_stable/couchbase-lite-ios/vendor/fmdb/src/FMDatabase.m:907
error: warning: couldn't get cmd pointer (substituting NULL): no variable named '_cmd' found in this frameExecution was interrupted, reason: breakpoint 1.3.
I noticed this code works fine on Couchbase Lite Beta 2 and breaks with Beta 3.
CBLManager.sharedInstance.dispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
So I'm a little confused why the test ok = dispatch_get_current_queue() == dispatchQueue; in beginUse would fail. Do you have any thoughts of what else I could be doing incorrectly to cause this assertion?
* frame #3: 0x0dbb4ad4 KiwiUnitTest`-[CBL_FMDatabase beginUse](self=0x0c8a5060, _cmd=<unavailable>) + 187 at FMDatabase.m:904frame #4: 0x0dbb3d35 KiwiUnitTest`-[CBL_FMDatabase executeQuery:withArgumentsInArray:orVAList:](self=<unavailable>, _cmd=0x0455520c, sql=<unavailable>, arrayArgs=0x0455520c, args=0xbfffbffc) + 195 at FMDatabase.m:515
[[NSAssertionHandler currentHandler] handleFailureInMethod:_cmd
object:self
file:@(__FILE__)
lineNumber:__LINE__
description:
@"***** THREAD-SAFETY VIOLATION: This database is being used on a thread it wasn't "
" created on! Please see the concurrency guidelines in the Couchbase Lite "
"documentation. *****"];
ok = dispatch_get_current_queue() == dispatchQueue;
Actually I take that back. Although I think the _cmd is what is actually causing the assertion it must be something with the threading that causes it to get to that assertion code due to this line.
ok = dispatch_get_current_queue() == dispatchQueue;
Would this test fail if the thread that the queue is running on changes? Would this test fail if a new instance of the queue was created even though it was created with the same name? From the traces I'm doing it seems like the code is running on the correct dispatchQueue however obviously something is triggering the thread assertion in FMDatabase. Thanks for your help as always.
If I'm understanding your code correctly then when the dispatchQueue is set in the CBLManager like this:CBLManager.sharedInstance.dispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
Out of curiosity if the dispatchQueue is set on CBLManager why is Couchbase Lite not just always running on that queue (as it's now required to do so otherwise an assertion will happen) regardless of the thread/queue of the calling entity?
That's right. Maybe that is causing the inconsistency.
I was trying to create my own DISPATCH_QUEUE_SERIAL earlier but ran into issues and abandoned that. I'll have to revisit this to see if it will fix the issue.
Since we're using models created on the main thread it seems that all communication then needs to be moved off onto a database dispatch queue using dispatch_sync unless I'm misunderstanding something.
Seems like if it's mandatory to run on the same thread or dispatch queue once it's defined in the CBL manager that it would be better to have it enforced and handled by CBL.