Lewis Donzis
|
pthread_sleepon_wait() bug
|
Lewis Donzis
04/05/2011 8:37 PM
post84651
|
pthread_sleepon_wait() bug
Source reference: /coreos_pub/trunk/lib/c/qnx/sleepon.c
pthread_sleepon_wait() is documented as having the sleepon lock when it wakes up. However, when pthread_sleepon_wait()
is canceled, it does not have the sleepon lock such that thread cleanup code gets an error when attempting to release
the sleepon lock. In addition, if any code is executed in the cleanup code that attempts to modify items under the
sleepon lock, they are unprotected...
While pthread_cond_wait() used to have this same problem back in QNX 6.2, since pthread_sleepon_wait() uses
pthread_cond_wait(), which has since been fixed, it should not be having this problem. However, there appears to be
some cleanup code pushed around the pthread_cond_wait(), and it looks like this cleanup code may be unlocking the
sleepon lock before it exits...
Obviously it is imperative that cleanup code that gets executed in the user's application due to pthread_sleepon_wait()
being canceled have the sleepon lock. The cleanup code cannot be taking action to cleanup items if it doesn't have the
sleepon lock. But, even in the simplest case, the cleanup code would be expected to at least unlock the sleepon lock.
Take the example from the documentation:
int _sleepon(void *addr) {
int ret;
if((ret = pthread_sleepon_lock()) == EOK) {
ret = pthread_sleepon_wait(addr);
pthread_sleepon_unlock();
}
return ret;
}
If this same example were to be made thread safe, it would look more like:
void _cleanup(void) {
pthread_sleepon_unlock();
}
int _sleepon(void *addr) {
int ret;
if((ret = pthread_sleepon_lock()) == EOK) {
pthread_cleanup_push(_cleanup, NULL);
ret = pthread_sleepon_wait(addr);
pthread_cleanup_pop(1); // pthread_sleepon_unlock();
}
return ret;
}
However, if the pthread_sleepon_wait() is canceled, then the cleanup code will get an error (even though it isn't
checking), trying to unlock the sleepon lock.
|
|
|