I'm reading stevens's book: apue. 2e. I have encountered a problem, about Mutex.
Let's see a peice of code first: (the following code comes from figure 11.10 of apue 2e)
#include <stdlib.h>
#include <pthread.h>
struct foo {
int f_count;
pthread_mutex_t f_lock;
/* ... more stuff here ... */
};
struct foo *
foo_alloc(void) /* allocate the object */
{
struct foo *fp;
if((fp = malloc(sizeof(struct foo))) != NULL){
fp->f_count = 1;
if(pthread_mutex_init(&fp->f_lock, NULL) != 0){
free(fp);
return NULL;
}
/* ... continue initialization ... */
}
return (fp);
}
void
foo_hold(struct foo *fp) /* add a reference to the object */
{
pthread_mutex_lock(&fp->f_lock);
fp->f_count++;
pthread_mutex_unlock(&fp->f_lock);
}
void
foo_rele(struct foo *fp) /* release a reference to the object */
{
pthread_mutex_lock(&fp->f_lock);
if(--fp->f_count == 0){ /* last reference */
pthread_mutex_unlock(&fp->f_lock); /* step 1 */
pthread_mutex_destroy(&fp->f_lock); /* step 2 */
free(fp);
}else{
pthread_mutex_unlock(&fp->f_lock);
}
}
Assuming we have two threads: thread1 and thread2. thread1 is running right now.
it calls function foo_rele and has finished the execution of step 1(see above), and prepare to execute step2.
however, context switch occurs at this moment. and thread2 starts to execute.
thread2 locks the lock fp->f_lock then does something. but before thread2 unlocks the lock, context switch occurs again.
thread2 stops executing and thread1 starts to execute. thread1 destroy the lock and it's known to us all that error generates.
so, my problem is: Is the situation mentioned above possible to happen? how can we avoid it and is there any interface(API) that can unlock and destroy a mutex atomically?