View Bug Activity | Format For Printing
POSIX indicates that pthread_cond_signal() is to return EINVAL if "The value cond does not refer to an initialized condition variable." This does not happen under pthread_cond_signal() in GLIBC: nptl/pthread_cond_signal.c
Created an attachment (id=2180) Testcase The following test-case demonstrates how a condition variable memset to zero does not return EINVAL. Currently the condition variable structure in GLIBC does not contain a method to indicate whether a condition variable has been initialized. Nor does the pthread_cond_signal() function check that the cond pointer is non-zero before dereferencing the pointer. Build test case with: gcc test_cond_signal.c -o cond_signal -lpthread Execute with: ./cond_signal 1 Expected result: creating thread 0 0 starting 0 exiting pthread cond signal failed for thread 0 with return value 22 Actual result: creating thread 0 0 starting 0 exiting calling cond signal 0
This is a may fail error, not a shall fail error. Testing whether something is uninitialized or not is very expensive, you can't use for it any bit in pthread_cond_t itself, since uninitialized var can have any value in it, you'd need on the side hashtable and that wouldn't work with process shared condvars. It is simply undefined behavior to use uninitialized condvars (and similarly for many other data structures).
Jakub, Isn't there a potential thread-safety issue with the way things currently are? Given the test-case, if the pthread_cond_signal() in the main thread executes prior to the memset which zeros out the condition variable following it's destruction in pthread_cond_destroy() there will be deadlock because the condition variable, in it's undefined state, still holds a lock. I tried offering a patch [http://sourceware.org/bugzilla/show_bug.cgi?id=5551] to at least release the condition variable lock in pthread_cond_destroy() but Ulrich rejected it as dangerous. I suppose a user level solution to this problem is to use a mutex to protect the condition variable array thereby allowing the condition variable to be exclusively locked and zeroed. I just want to make sure that this isn't an oversight.
Apologies for re-opening but I'd like Jakub to comment on my previous question regarding thread-safety issues.
Your testcase is racy, that's not the fault of libpthread. If you use a synchronization primitive in several threads (condvar in this case), then you need to ensure it is already initialized and not yet destroyed when it is used. That can be done by initializing it prior to starting the threads, or by using some locking, barriers, etc.