int ret;
OrigFn fn;
unsigned long mutex_is_valid;
+ Bool abstime_is_valid;
VALGRIND_GET_ORIG_FN(fn);
if (TRACE_PTH_FNS) {
pthread_cond_t*,cond, pthread_mutex_t*,mutex);
assert(mutex_is_valid == 1 || mutex_is_valid == 0);
+ abstime_is_valid = abstime->tv_nsec >= 0 && abstime->tv_nsec < 1000000000;
+
/* Tell the tool we're about to drop the mutex. This reflects the
fact that in a cond_wait, we show up holding the mutex, and the
call atomically drops the mutex and waits for the cv to be
signalled. */
- if (mutex_is_valid) {
+ if (mutex_is_valid && abstime_is_valid) {
DO_CREQ_v_W(_VG_USERREQ__HG_PTHREAD_MUTEX_UNLOCK_PRE,
pthread_mutex_t*,mutex);
}
CALL_FN_W_WWW(ret, fn, cond,mutex,abstime);
+ if (!abstime_is_valid && ret != EINVAL) {
+ DO_PthAPIerror("Bug in libpthread: pthread_cond_timedwait "
+ "invalid abstime did not cause"
+ " EINVAL", ret);
+ }
+
if ((ret == 0 || ret == ETIMEDOUT) && mutex_is_valid) {
/* and now we have the mutex again */
DO_CREQ_v_W(_VG_USERREQ__HG_PTHREAD_MUTEX_LOCK_POST,
annotate_rwlock.stderr.exp \
annotate_smart_pointer.vgtest annotate_smart_pointer.stdout.exp \
annotate_smart_pointer.stderr.exp \
+ cond_timedwait_invalid.vgtest cond_timedwait_invalid.stdout.exp \
+ cond_timedwait_invalid.stderr.exp
bar_bad.vgtest bar_bad.stdout.exp bar_bad.stderr.exp \
bar_trivial.vgtest bar_trivial.stdout.exp bar_trivial.stderr.exp \
free_is_write.vgtest free_is_write.stdout.exp \
# should be conditionally compiled like tc20_verifywrap is.
check_PROGRAMS = \
annotate_hbefore \
+ cond_timedwait_invalid \
free_is_write \
hg01_all_ok \
hg02_deadlock \
annotate_hbefore_CFLAGS = $(AM_CFLAGS)
endif
+if VGCONF_OS_IS_LINUX
+cond_timedwait_invalid_LDADD = -lrt
+endif
--- /dev/null
+#include <time.h>
+#include <pthread.h>
+#include <assert.h>
+#include <errno.h>
+
+int main()
+{
+ struct timespec abstime;
+ pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+ pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+
+ assert(clock_gettime(CLOCK_REALTIME, &abstime)==0);
+ abstime.tv_nsec += 1000000000;
+
+ assert(pthread_mutex_lock(&mutex)==0);
+ assert(pthread_cond_timedwait(&cond, &mutex, &abstime)==EINVAL);
+ assert(pthread_mutex_unlock(&mutex)==0);
+
+ return 0;
+}
--- /dev/null
+
+---Thread-Announcement------------------------------------------
+
+Thread #x is the program's root thread
+
+----------------------------------------------------------------
+
+Thread #x's call to pthread_cond_timedwait failed
+ with error code 22 (EINVAL: Invalid argument)
+ at 0x........: pthread_cond_timedwait_WRK (hg_intercepts.c:...)
+ by 0x........: pthread_cond_timedwait@* (hg_intercepts.c:...)
+ by 0x........: main (cond_timedwait_invalid.c:16)
+
+
+ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
--- /dev/null
+prog: cond_timedwait_invalid
+