First user will be posix compat aio. Signed-off-by: Jan Kiszka <jan.kis...@siemens.com> --- qemu-thread-posix.c | 22 ++++++++++++++++++++++ qemu-thread-win32.c | 16 +++++++++++++++- qemu-thread.h | 2 ++ 3 files changed, 39 insertions(+), 1 deletions(-)
diff --git a/qemu-thread-posix.c b/qemu-thread-posix.c index f76427e..1d970fb 100644 --- a/qemu-thread-posix.c +++ b/qemu-thread-posix.c @@ -17,6 +17,7 @@ #include <signal.h> #include <stdint.h> #include <string.h> +#include <sys/time.h> #include "qemu-thread.h" static void error_exit(int err, const char *msg) @@ -115,6 +116,27 @@ void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex) error_exit(err, __func__); } +int qemu_cond_timedwait(QemuCond *cond, QemuMutex *mutex, + unsigned int timeout_ms) +{ + struct timespec ts; + struct timeval tv; + int err; + + gettimeofday(&tv, NULL); + ts.tv_sec = tv.tv_sec + timeout_ms / 1000; + ts.tv_nsec = tv.tv_usec * 1000 + timeout_ms % 1000; + if (ts.tv_nsec > 1000000000) { + ts.tv_sec++; + ts.tv_nsec -= 1000000000; + } + err = pthread_cond_timedwait(&cond->cond, &mutex->lock, &ts); + if (err && err != ETIMEDOUT) { + error_exit(err, __func__); + } + return err == 0; +} + void qemu_thread_create(QemuThread *thread, void *(*start_routine)(void*), void *arg, int mode) diff --git a/qemu-thread-win32.c b/qemu-thread-win32.c index 4819ff4..1b01a8b 100644 --- a/qemu-thread-win32.c +++ b/qemu-thread-win32.c @@ -158,6 +158,14 @@ void qemu_cond_broadcast(QemuCond *cond) void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex) { + qemu_cond_timedwait(cond, mutex, INFINITE); +} + +int qemu_cond_timedwait(QemuCond *cond, QemuMutex *mutex, + unsigned int timeout_ms) +{ + DWORD result; + /* * This access is protected under the mutex. */ @@ -170,7 +178,11 @@ void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex) * leaving mutex unlocked before we wait on semaphore. */ qemu_mutex_unlock(mutex); - WaitForSingleObject(cond->sema, INFINITE); + result = WaitForSingleObject(cond->sema, timeout_ms); + + if (result != WAIT_OBJECT_0 && result != WAIT_TIMEOUT) { + error_exit(GetLastError(), __func__); + } /* Now waiters must rendez-vous with the signaling thread and * let it continue. For cond_broadcast this has heavy contention @@ -190,6 +202,8 @@ void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex) } qemu_mutex_lock(mutex); + + return result == WAIT_OBJECT_0; } struct QemuThreadData { diff --git a/qemu-thread.h b/qemu-thread.h index aa1ae55..8be48e4 100644 --- a/qemu-thread.h +++ b/qemu-thread.h @@ -33,6 +33,8 @@ void qemu_cond_destroy(QemuCond *cond); void qemu_cond_signal(QemuCond *cond); void qemu_cond_broadcast(QemuCond *cond); void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex); +int qemu_cond_timedwait(QemuCond *cond, QemuMutex *mutex, + unsigned int timeout_ms); void qemu_thread_create(QemuThread *thread, void *(*start_routine)(void *), -- 1.7.3.4