I have a process-shared pthread condition (with associated mutex). What would happen if a process waiting on this condition (using pthread_cond_wait() or pthread_cond_timedwait()) gets terminated? Can this condition still be used by other processes?
In my scenario process #1 waits on the condition and gets terminated. Process #2 at some point sees that it's the only one now using the condition and calls pthread_cond_destroy().
What i m seeing is that pthread_cond_destroy() simply hangs. Has anyone encountered the same problem?
From the man page of pthread_cond_destroy() it says that destroying the condition on which some thread is still waiting results in undefined behavior. In my case nobody is waiting anymore when process #2 calls pthread_cond_destroy() because the waiting process #1 was terminated, but apparently the condition itself still thinks there is a waiting thread.
Is there any way around this problem?
Edit:
Per request, i post the sample programs (i reversed p1 & p2 here):
p1.cpp:
#include <sys/types.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
struct MyCond {
pthread_mutex_t m;
pthread_cond_t c;
};
int main()
{
pthread_mutexattr_t ma;
pthread_mutexattr_init(&ma);
pthread_mutexattr_setpshared(&ma, PTHREAD_PROCESS_SHARED);
pthread_condattr_t ca;
pthread_condattr_init(&ca);
pthread_condattr_setpshared(&ca, PTHREAD_PROCESS_SHARED);
int fd = shm_open("/test_cond_p", O_RDWR|O_CREAT, 0666);
ftruncate(fd, sizeof(MyCond));
MyCond *c = (MyCond *)mmap(NULL, sizeof(MyCond),
PROT_READ | PROT_WRITE, MAP_SHARED,fd, 0);
//close (fd);
pthread_mutex_init(&c->m, &ma);
pthread_cond_init(&c->c, &ca);
printf("Inited MyCond, %x\n", c);
puts("Press Enter to continue");
fgetc(stdin);
int r = pthread_cond_signal(&c->c);
printf("After pthread_cond_signal, r=%d\n", r);
puts("Before pthread_cond_destroy");
r = pthread_cond_destroy(&c->c);
printf("After pthread_cond_destroy, r=%d\n", r);
r = pthread_mutex_destroy(&c->m);
printf("After pthread_mutex_destroy, r=%d\n", r);
munmap(c, sizeof(MyCond));
shm_unlink("/test_cond_p");
return 0;
}
p2.cpp:
#include <sys/types.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/time.h>
struct MyCond {
pthread_mutex_t m;
pthread_cond_t c;
};
int main()
{
int fd = shm_open("/test_cond_p", O_RDWR, 0666);
MyCond *c = (MyCond *)mmap(NULL, sizeof(MyCond),
PROT_READ | PROT_WRITE, MAP_SHARED,fd, 0);
//close (fd);
pthread_mutex_lock(&c->m);
puts("Before pthread_cond_wait");
int r = pthread_cond_wait(&c->c, &c->m);
printf("After pthread_cond_wait, r=%d\n", r);
munmap(c, sizeof(MyCond));
return 0;
}
Run p1 first, then run p2, after it says "before pthread_cond_wait", Ctrl-C it. Then press Enter in p1's shell.
At first, i was not able to reproduce the hang, but i had both pthread_cond_destroy() and pthread_mutex_destroy() to return EBUSY.
But now the hang reproduces if we call pthread_cond_signal() before pthread_cond_destroy() (see the code above).