diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index f5e5518e4e..b360e7126f 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -452,6 +452,7 @@ virMutexUnlock;
 virCondInit;
 virCondDestroy;
 virCondWait;
+virCondWaitUntil;
 virCondSignal;
 virCondBroadcast;
 
diff --git a/src/util/threads-pthread.c b/src/util/threads-pthread.c
index b3ec06ea2e..ad42483c1d 100644
--- a/src/util/threads-pthread.c
+++ b/src/util/threads-pthread.c
@@ -88,6 +88,21 @@ int virCondWait(virCondPtr c, virMutexPtr m)
     return 0;
 }
 
+int virCondWaitUntil(virCondPtr c, virMutexPtr m, unsigned long long whenms)
+{
+    int ret;
+    struct timespec ts;
+
+    ts.tv_sec = whenms / 1000;
+    ts.tv_nsec = (whenms % 1000) * 1000;
+
+    if ((ret = pthread_cond_timedwait(&c->cond, &m->lock, &ts)) != 0) {
+        errno = ret;
+        return -1;
+    }
+    return 0;
+}
+
 void virCondSignal(virCondPtr c)
 {
     pthread_cond_signal(&c->cond);
diff --git a/src/util/threads.h b/src/util/threads.h
index 62239b711d..d97463d624 100644
--- a/src/util/threads.h
+++ b/src/util/threads.h
@@ -49,6 +49,7 @@ int virCondInit(virCondPtr c) ATTRIBUTE_RETURN_CHECK;
 int virCondDestroy(virCondPtr c) ATTRIBUTE_RETURN_CHECK;
 
 int virCondWait(virCondPtr c, virMutexPtr m) ATTRIBUTE_RETURN_CHECK;
+int virCondWaitUntil(virCondPtr c, virMutexPtr m, unsigned long long whenms) ATTRIBUTE_RETURN_CHECK;
 void virCondSignal(virCondPtr c);
 void virCondBroadcast(virCondPtr c);