Sign in to follow this  

PThreads: I'm creating a dead lock?

This topic is 815 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm doing c++ on Android and I'm having some trouble with pthreads. I'm wondering if I am creating a dead lock?
 
The issue I am having is that, when ever I try to kill my application (hold down home and swipe right to remove from recent app list) I never see the onDestroy method get triggered
 
Can someone tell me if I'm accidentally creating a dead lock and stalling?
 
CoreApplication* Core::ApplicationCreate(ANativeActivity* activity)
{
    CoreApplication* application = new CoreApplication();
    application->activity = activity;
 
    
//------[ PTHREAD SETUP ]--------------
pthread_mutex_init(&application->mutex, NULL);
    pthread_cond_init(&application->cond, NULL);
 
    pthread_attr_t attr; 
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    pthread_create(&application->thread, &attr, ApplicationEntry, application);
 
    //Stall this thread until we are running!
    pthread_mutex_lock(&application->mutex);
    while (application->running == false)
        pthread_cond_wait(&application->cond, &application->mutex);
    pthread_mutex_unlock(&application->mutex);
 
 
    return application;
}
 
//The call back for on destory
void Core::onDestroy(ANativeActivity* activity)
{
     //Stall until we have cleaned up
    pthread_mutex_lock(&application->mutex);
application->running = false;
    while (application->cleanUpFinished == false)
        pthread_cond_wait(&application->cond, &application->mutex);
    pthread_mutex_unlock(&application->mutex);
 

    pthread_cond_destroy(&application->appThreadCond);
    pthread_mutex_destroy(&application->appThreadMutex);
 
    delete application;
    application = NULL;

}

//----------- [++++] PTHREAD STUFF [++++]
//The Pthread method to run
void *Core::ApplicationEntry(void* param)
{      
       CoreApplication* application = (CoreApplication*)param;

       //State that we are running! Tell everyone that is waiting on the condition
       pthread_mutex_lock(&application->mutex);
       application->running = true;
       pthread_cond_broadcast(&application->cond);
       pthread_mutex_unlock(&application->mutex);
       
       ApplicationMain(application); 
       ApplicationCleanup(application);
       
       return NULL;
}

void Core::ApplicationMain(CoreApplication* application)
{   
    //Run until we are told not to
    while(application->running)
    { 
        //NOthing done in this method for now
    }
}

void Core::ApplicationCleanup(CoreApplication* application)
{
   pthread_mutex_lock(&application->mutex);
   application->cleanUpFinished = true;
   pthread_cond_broadcast(&application->cond);
   pthread_mutex_unlock(&application->mutex);
}  

Edited by noodleBowl

Share this post


Link to post
Share on other sites

I don't see it with the code you pasted, but that doesn't mean it isn't happening.

 

Also, note that onDestroy() is not guaranteed to be called. There are many ways for your application to terminate or be killed where onDestroy is not executed.

 

 

As far as a deadlock or block is concerned....

 

Many operations block execution. Blocking operations are plentiful across all code bases.

 

Deadlock is a special kind of blocking scenario. A deadlock is when one blocking operation is blocked by another blocking operation, and the two form a cycle. A is waiting for B, and B is waiting for A, or more graphically, A-->B-->A. Or it may be a bigger cycle of A-->B-->C-->A.  Or A-->B-->C-->D-->A.  

 

Since you're writing about mutex locks specifically, a common bug for beginners is to not always acquire a mutex in the right order.  If there is ever a situation where you have more than one mutex in your system, you must guarantee that you acquire them in a consistent order. If one system acquires A then B, and another system acquires B then A, you've just built the conditions for a deadlock, two systems waiting for each other.

 

A common way to do this is build a locking protocol for your app. Every mutex is given a priority. You can only acquire a mutex if no lower-priority mutex has already been established. Think of it as a fixed array of values for every mutex. If you want to acquire mutex #21, you can only do it if mutexes #22, #23, #24, and following are also all unlocked. If you need to acquire two mutexes, they need to be acquired with the lowest value first. You also need to handle cases where you cannot acquire the mutex at the present time.

 

It is entirely possible that somewhere in your code you wrote some blocking operations or trigger a deadlock. 

Share this post


Link to post
Share on other sites

This topic is 815 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this