mirror of
https://github.com/wolfcw/libfaketime.git
synced 2026-05-17 00:26:16 +03:00
Don't use _try_ locking calls for monotonic_conds_lock
This reverts commit8ef74e33b6"Swapped out pthread_rwlock_xxlock() ..." This could result in concurrent uses of pthread_cond_* erroneously returning EAGAIN, which is not permitted by the spec and which the application way well treat as a bug. This seems to be happening in gem2deb in ci.debian.net. The commit message in8ef74e33b6says (rewrapped) Swapped out pthread_rwlock_xxlock(), which doesn't return if it can't obtain the lock, with pthread_rwlock_xxtrylock() followed by sched yield and error code return. The issue is sometimes a thread calling pthread_cond_init() or pthread_cond_destroy() can't acquire the lock when another thread is waiting on a condition variable notification via pthread_cond_timedwait(), and thus the thread calling pthread_cond_init() or pthread_cond_destroy() end up hanging indefinitely. I don't think this is true. The things that are done with monotonic_conds_lock held are HASH_ADD_PTR HASH_FIND_PTR etc. on monotonic_conds, which should all be fast and AFAICT don't in turn take any locks. So it shouldn't deadlock. I conjecture that the underlying bug being experienced by the author of "Swapped out pthread_rwlock_xxlock" was the lack of ftpl_init - ie, access to an uninitialised pthread_rwlock_t. That might result in a hang.
This commit is contained in:
@@ -3690,9 +3690,9 @@ int pthread_cond_init_232(pthread_cond_t *restrict cond, const pthread_condattr_
|
||||
struct pthread_cond_monotonic *e = (struct pthread_cond_monotonic*)malloc(sizeof(struct pthread_cond_monotonic));
|
||||
e->ptr = cond;
|
||||
|
||||
if (pthread_rwlock_trywrlock(&monotonic_conds_lock) != 0) {
|
||||
sched_yield();
|
||||
return EAGAIN;
|
||||
if (pthread_rwlock_wrlock(&monotonic_conds_lock) != 0) {
|
||||
fprintf(stderr,"can't acquire write monotonic_conds_lock\n");
|
||||
exit(-1);
|
||||
}
|
||||
HASH_ADD_PTR(monotonic_conds, ptr, e);
|
||||
pthread_rwlock_unlock(&monotonic_conds_lock);
|
||||
@@ -3707,9 +3707,9 @@ int pthread_cond_destroy_232(pthread_cond_t *cond)
|
||||
|
||||
ftpl_init();
|
||||
|
||||
if (pthread_rwlock_trywrlock(&monotonic_conds_lock) != 0) {
|
||||
sched_yield();
|
||||
return EBUSY;
|
||||
if (pthread_rwlock_wrlock(&monotonic_conds_lock) != 0) {
|
||||
fprintf(stderr,"can't acquire write monotonic_conds_lock\n");
|
||||
exit(-1);
|
||||
}
|
||||
HASH_FIND_PTR(monotonic_conds, &cond, e);
|
||||
if (e) {
|
||||
@@ -3793,9 +3793,9 @@ int pthread_cond_timedwait_common(pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
|
||||
if (abstime != NULL)
|
||||
{
|
||||
if (pthread_rwlock_tryrdlock(&monotonic_conds_lock) != 0) {
|
||||
sched_yield();
|
||||
return EAGAIN;
|
||||
if (pthread_rwlock_rdlock(&monotonic_conds_lock) != 0) {
|
||||
fprintf(stderr,"can't acquire read monotonic_conds_lock\n");
|
||||
exit(-1);
|
||||
}
|
||||
HASH_FIND_PTR(monotonic_conds, &cond, e);
|
||||
pthread_rwlock_unlock(&monotonic_conds_lock);
|
||||
|
||||
Reference in New Issue
Block a user