Jump to content
  • Advertisement
Sign in to follow this  
noodleBowl

PThreads: I'm creating a dead lock?

This topic is 1122 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
Advertisement

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
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!