Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Could not delete the database using deletedatabase method #418

Closed
rubha opened this issue Aug 14, 2014 · 16 comments
Closed

Could not delete the database using deletedatabase method #418

rubha opened this issue Aug 14, 2014 · 16 comments

Comments

@rubha
Copy link

rubha commented Aug 14, 2014

In our application we need to delete the database on logout and create new database on login. We have put the activity indicator view till the delete action completes , which is keep on loading and the delete database action never comes to end ,not throwing an exception too. we have implemented it in the following way:

CBLDatabase *database=[[CBLManager sharedInstance]databaseNamed:kCBLDataBaseName error:&error];
BOOL status= [database deleteDatabase:&error];
if(!status){
NSLog(@"error while deleting the database =%@",error.localizedDescription)
}

@snej
Copy link
Contributor

snej commented Aug 15, 2014

When this happens, please pause the app in Xcode and get a backtrace (bt command) of the thread that's stuck in the delete call. Post the backtrace here.

@rubha
Copy link
Author

rubha commented Aug 18, 2014

Sorry wrongly closed this issue.

Please find a backtrace. we are deleting the database in a detached thread (thread 15)

thread #1: tid = 0x2817f, 0x037e93ba libsystem_kernel.dylib__kill + 10, queue = 'com.apple.main-thread', stop reason = signal SIGKILL 
frame #0: 0x037e93ba libsystem_kernel.dylib__kill + 10
frame #1: 0x037e84b8 libsystem_kernel.dylibkill$UNIX2003 + 32 
frame #2: 0x02885df6 CoreFoundation__CFRunLoopServiceMachPort + 310
frame #3: 0x0288b35d CoreFoundation__CFRunLoopRun + 1341 
frame #4: 0x0288a9d3 CoreFoundationCFRunLoopRunSpecific + 467
frame #5: 0x0288a7eb CoreFoundationCFRunLoopRunInMode + 123 
frame #6: 0x039375ee GraphicsServicesGSEventRunModal + 192
frame #7: 0x0393742b GraphicsServicesGSEventRun + 104 
frame #8: 0x00fc4f9b UIKitUIApplicationMain + 1225
frame #9: 0x001c5f9d CC.0.0.27jun`main(argc=1, argv=0xbfffee14) + 141 at main.m:16

thread #2: tid = 0x2822f, 0x037ea9ca libsystem_kernel.dylibkevent64 + 10, queue = 'com.apple.libdispatch-manager' 
frame #0: 0x037ea9ca libsystem_kernel.dylibkevent64 + 10
frame #1: 0x033dcf36 libdispatch.dylib_dispatch_mgr_invoke + 238 
frame #2: 0x033dcc72 libdispatch.dylib_dispatch_mgr_thread + 60

thread #5: tid = 0x28233, 0x037e77ce libsystem_kernel.dylibmach_msg_trap + 10, name = 'CouchbaseLite' 
frame #0: 0x037e77ce libsystem_kernel.dylibmach_msg_trap + 10
frame #1: 0x037e6cac libsystem_kernel.dylibmach_msg + 68 
frame #2: 0x02885d69 CoreFoundationCFRunLoopServiceMachPort + 169
frame #3: 0x0288b2c1 CoreFoundation__CFRunLoopRun + 1185 
frame #4: 0x0288a9d3 CoreFoundationCFRunLoopRunSpecific + 467
frame #5: 0x0288a7eb CoreFoundationCFRunLoopRunInMode + 123 
frame #6: 0x00c0ee35 Foundation-[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 284
frame #7: 0x00313d8b CC.0.0.27jun-[CBL_Server runServerThread](self=<unavailable>, _cmd=0x003922a5) + 349 at CBL_Server.m:110 
frame #8: 0x00c09a07 Foundation-[NSThread main] + 76
frame #9: 0x00c09966 Foundation`__NSThread__main + 1275
frame #10: 0x036a45b7 libsystem_c.dylib`_pthread_start + 344

    thread #15: tid = 0x2835a, 0x037e9c72 libsystem_kernel.dylib__semwait_signal + 10 
frame #0: 0x037e9c72 libsystem_kernel.dylib__semwait_signal + 10
frame #1: 0x034a62df libsystem_sim_c.dylibnanosleep + 219 
frame #2: 0x034a618a libsystem_sim_c.dylibusleep + 60
frame #3: 0x00361bfe CC.0.0.27jun-[CBL_Shared forgetDatabaseNamed:](self=0x0a568570, _cmd=0x00395da9, dbName=0x0046de90) + 64 at CBL_Shared.m:106 
frame #4: 0x0035038d CC.0.0.27jun-[CBLManager(self=0x128b69e0, cmd=0x00394d31, db=0x120c50a0) forgetDatabase:] + 255 at CBLManager.m:570 
frame #5: 0x003459f1 CC.0.0.27jun-[CBLDatabase closeForDeletion](self=0x120c50a0, _cmd=0x00394d42) + 349 at CBLDatabase.m:191 
frame #6: 0x00345aa1 CC.0.0.27jun-CBLDatabase deleteDatabase: + 142 at CBLDatabase.m:200 
frame #7: 0x0007705e CC.0.0.27jun-[CCMainViewController reCreateDataBase](self=0x132f1800, _cmd=0x0037b91c) + 398 at CCMainViewController.m:1050 
frame #8: 0x00c09a07 Foundation-[NSThread main] + 76 
frame #9: 0x00c09966 Foundation`__NSThread__main + 1275 
frame #10: 0x036a45b7 libsystem_c.dylib`_pthread_start + 344

    thread #18: tid = 0x28697, 0x037ea0ee libsystem_kernel.dylib__workq_kernreturn + 10 
frame #0: 0x037ea0ee libsystem_kernel.dylib__workq_kernreturn + 10
frame #1: 0x036a70ac libsystem_c.dylib_pthread_workq_return + 45 
frame #2: 0x036a6e79 libsystem_c.dylib_pthread_wqthread + 448

@snej
Copy link
Contributor

snej commented Aug 18, 2014

The formatting was pretty messed-up so I edited the above stack dump to clarify it.
forgetDatabaseNamed: is blocking waiting for something to complete but there are no other threads doing anything... something's gone wrong, clearly.

@rubha
Copy link
Author

rubha commented Aug 19, 2014

sorry about the formatting.Bit confused with the editor.
I am testing with couchbase lite1.0 beta3 release , if i dont create a copy of cblmanager and try to delete the database, its working fine. But I am getting this below warning,If i try to create the copy of cblmanager, close it and then deleting the database of it. Main thread is also blocked.

<CBL_Shared: 0xa559bd0>: Still waiting to -forgetDatabaseNamed: "couchbaseDb"

Back trace:
 thread #1: tid = 0x897a2, 0x037f1c72 libsystem_kernel.dylib`__semwait_signal + 10, queue = 'com.apple.main-thread'
    frame #0: 0x037f1c72 libsystem_kernel.dylib`__semwait_signal + 10
    frame #1: 0x034ae2df libsystem_sim_c.dylib`nanosleep + 219
    frame #2: 0x034ae18a libsystem_sim_c.dylib`usleep + 60
    frame #3: 0x00348f5a CabinCrew.0.0.27jun`-[CBL_Shared forgetDatabaseNamed:]  (self=0x00000001, _cmd=0x00396782, dbName=0x00471b1c) + 172 at CBL_Shared.m:107
    frame #4: 0x00336fe1 CabinCrew.0.0.27jun`-[CBLManager(self=0x0a2d3750, _cmd=0x003949c7, db=0x0a2d4c00) _forgetDatabase:] + 255 at CBLManager.m:462
    frame #5: 0x0032d18b CabinCrew.0.0.27jun`-[CBLDatabase closeForDeletion](self=0x0a2d4c00, _cmd=0x003949d8) + 359 at CBLDatabase.m:193
    frame #6: 0x002f1776 CabinCrew.0.0.27jun`__35-[CBLDatabase(.block_descriptor=0x0a2e9a60) dbChanged:]_block_invoke302 + 50 at CBLDatabase+Internal.m:656
    frame #7: 0x033de7b8 libdispatch.dylib`_dispatch_call_block_and_release + 15
    frame #8: 0x033f34d0 libdispatch.dylib`_dispatch_client_callout + 14
    frame #9: 0x033e1726 libdispatch.dylib`_dispatch_main_queue_callback_4CF + 340
    frame #10: 0x0295243e CoreFoundation`__CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 14
    frame #11: 0x028935cb CoreFoundation`__CFRunLoopRun + 1963
    frame #12: 0x028929d3 CoreFoundation`CFRunLoopRunSpecific + 467
    frame #13: 0x028927eb CoreFoundation`CFRunLoopRunInMode + 123
    frame #14: 0x0393f5ee GraphicsServices`GSEventRunModal + 192
    frame #15: 0x0393f42b GraphicsServices`GSEventRun + 104
    frame #16: 0x00fccf9b UIKit`UIApplicationMain + 1225
    frame #17: 0x001c5a5d cctest.0.0.27jun`main(argc=1, argv=0xbfffee14) + 141 at main.m:16

After deleting the database,the copy's CBL_Shared object's "opendatabases"count is 0, whereas the main manager (sharedinstance) CBL_Shared object's "opendatabases" count is 1,
Printing description of manager->_shared->_databases:

{
    cctest =     {
        filter =         {
            sharedDocuments = "<__NSGlobalBlock__: 0x4303e0>";
        };
    };
}

Printing description of managerCopy->_shared->_databases:
(NSMutableDictionary *) _databases =

Am i missing out anything?

@snej
Copy link
Contributor

snej commented Aug 20, 2014

Re. the formatting — use a line of three back-quotes to begin or end a block of raw text (code or stack dumps or whatever.)

@pasin pasin reopened this Aug 20, 2014
@pasin pasin added in progress and removed ready labels Aug 20, 2014
@rubha
Copy link
Author

rubha commented Aug 25, 2014

Hi, Should i start working on this commit ?? If it needs to be merged to the master,when it would be completed ?? I have to fix the defect based on this issue in our application asap, as this issue is of high priority.

Thanks.

@pasin
Copy link
Contributor

pasin commented Aug 25, 2014

@rubha , I will need to make a small change to the commit per @snej's review. The fix should be ready soon.

pasin added a commit that referenced this issue Aug 25, 2014
* Per code review, revert changes in CBL_Shared back to use usleep instead of using NSRunLoop to wait.

* Update API_DeleteDatabase to ensure that the copied manager is closed and add test for the case that multiple managers working on different threads.
@pasin pasin closed this as completed in 3f964a1 Aug 25, 2014
snej added a commit that referenced this issue Aug 25, 2014
Fix #418 deleteDatabase: blocking thread
@pasin
Copy link
Contributor

pasin commented Aug 25, 2014

@rubha, the fix has been merged to the master.

@rubha
Copy link
Author

rubha commented Aug 26, 2014

Thanks Pasin. There is a latest release of couchbase lite 1.0.2,but this fix is not available in that release.When would be the next release? How can i make use of this commit from the master now ?

@snej
Copy link
Contributor

snej commented Aug 26, 2014

I don't think there's a schedule for 1.0.3 yet, but last I heard we are hoping to push a release every few weeks.

You can get the fix now by checking out the master branch in Git and building it yourself.

@rubha
Copy link
Author

rubha commented Sep 1, 2014

Thanks Snej. I built the framework and integrated it into my project and tested. I am able to delete the database successfully,if i delete the database of the manager's copy created in a detached thread.

CBLDatabase *database=[[[CBLManager sharedInstance]copy]databaseNamed:kCBLDataBaseName error:&error];

But if i try to delete the database in main thread,
CBLDatabase *database=[[CBLManager sharedInstance]databaseNamed:kCBLDataBaseName error:&error];

I could not delete it.Still getting the same below warning,though i have closed all the copies of the manager's created,
WARNING: <CBL_Shared: 0xa3c5bc0>: Still waiting to -forgetDatabaseNamed: "ccTest"

@snej
Copy link
Contributor

snej commented Sep 1, 2014

Can you show the actual code you use? And make sure you're not calling a CBLDatabase or CBLManager on the wrong thread.

@pasin
Copy link
Contributor

pasin commented Sep 1, 2014

Using 2 managers operating and deleting a database on the same thread is not an ideal case and deleting the database will get blocked.

From the code that you posted, please try to close the copied manager before deleting the same database getting from the shared manager on the same thread the following.

CBLManager *copiedManager = [[[CBLManager sharedInstance]copy];
CBLDatabase *database=[copiedManager databaseNamed:kCBLDataBaseName error:&error];

// But if i try to delete the database in main thread
[copiedManager close];
CBLDatabase *database=[[CBLManager sharedInstance]databaseNamed:kCBLDataBaseName error:&error];

@rubha
Copy link
Author

rubha commented Sep 2, 2014

I am trying to delete the database in mainthread as,

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if(buttonIndex==1){
[[UIApplication sharedApplication] cancelAllLocalNotifications];
[self deleteDatabase];
}
}

-(void)deleteDatabase{
NSError *error;
CBLDatabase *database=[[CBLManager sharedInstance]databaseNamed:kCBLDataBaseName error:&error];
if ([database deleteDatabase:&error]) {
CCLog(@"deletion sucess");
database=nil;
}else{
CCLog(@"error while deleting the database=%@",error.localizedDescription);
}
}

@rubha
Copy link
Author

rubha commented Sep 2, 2014

Pasin ,I am closing all the copies of manager's created, once its job is done and before deleting the database also. Its working fine. For the same above scenario, instead of deleting the database in main thread, if i detach a thread and try to delete it , its working

-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if(buttonIndex==1){
[NSThread detachNewThreadSelector:@selector(doDeleteDatabase) toTarget:self withObject:nil];
}

-(void)doDeleteDatabase{
NSError *error;
CBLDatabase *database=[[[CBLManager sharedInstance]copy]databaseNamed:kCBLDataBaseName error:&error];
[database.manager close];
if ([database deleteDatabase:&error]) {
CCLog(@"deletion sucess");
database=nil;
}else{
CCLog(@"error while deleting the database=%@",error.localizedDescription);
}
}

@pasin
Copy link
Contributor

pasin commented Sep 3, 2014

@rubha, It's difficult to help without seeing the whole code.

I created a gist containing my test code that works, and the code is deleting the database on the main thread. Could you please check the gist below and compare with your code to see differences? The key is that I closed the copied manager so that the database referenced by that manager is closed before deleting the database (See line 17 in the gist).

https://gist.github.com/4e3b6d409c5a5cedc1ed.git

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

No branches or pull requests

5 participants