[vlc-commits] interrupt: add vlc_mwait_i11e() and vlc_msleep_i11e()

Rémi Denis-Courmont git at videolan.org
Mon Jul 6 19:04:59 CEST 2015


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Mon Jul  6 19:43:39 2015 +0300| [2ca95bb11a053087a8ea853375305ec01b07e20e] | committer: Rémi Denis-Courmont

interrupt: add vlc_mwait_i11e() and vlc_msleep_i11e()

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=2ca95bb11a053087a8ea853375305ec01b07e20e
---

 include/vlc_interrupt.h |   27 +++++++++++++++++++++++++++
 src/libvlccore.sym      |    1 +
 src/misc/interrupt.c    |   44 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 72 insertions(+)

diff --git a/include/vlc_interrupt.h b/include/vlc_interrupt.h
index eb3c564..b4aba1c 100644
--- a/include/vlc_interrupt.h
+++ b/include/vlc_interrupt.h
@@ -63,6 +63,33 @@ struct msghdr;
 VLC_API int vlc_sem_wait_i11e(vlc_sem_t *);
 
 /**
+ * Interruptible variant of mwait().
+ *
+ * Waits for a specified timestamp or, if the calling thread has an
+ * interruption context, an interruption.
+ *
+ * @return EINTR if an interruption occurred, otherwise 0 once the timestamp is
+ * reached.
+ */
+VLC_API int vlc_mwait_i11e(mtime_t);
+
+/**
+ * Interruptible variant of msleep().
+ *
+ * Waits for a specified timeout duration or, if the calling thread has an
+ * interruption context, an interruption.
+ *
+ * @param delay timeout value (in microseconds)
+ *
+ * @return EINTR if an interruption occurred, otherwise 0 once the timeout
+ * expired.
+ */
+static inline int vlc_msleep_i11e(mtime_t delay)
+{
+    return vlc_mwait_i11e(mdate() + delay);
+}
+
+/**
  * Interruptible variant of poll().
  *
  * Waits for file descriptors I/O events, a timeout, a signal or a VLC I/O
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index 9047646..a145079 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -550,6 +550,7 @@ vlc_sendmsg_i11e
 vlc_sendto_i11e
 vlc_accept_i11e
 vlc_sem_wait_i11e
+vlc_mwait_i11e
 vlc_interrupt_create
 vlc_interrupt_destroy
 vlc_interrupt_set
diff --git a/src/misc/interrupt.c b/src/misc/interrupt.c
index 7ec7fa9..7b25cd7 100644
--- a/src/misc/interrupt.c
+++ b/src/misc/interrupt.c
@@ -258,6 +258,50 @@ int vlc_sem_wait_i11e(vlc_sem_t *sem)
     return vlc_interrupt_finish(ctx);
 }
 
+static void vlc_mwait_i11e_wake(void *opaque)
+{
+    vlc_cond_signal(opaque);
+}
+
+static void vlc_mwait_i11e_cleanup(void *opaque)
+{
+    vlc_interrupt_t *ctx = opaque;
+    vlc_cond_t *cond = ctx->data;
+
+    vlc_mutex_unlock(&ctx->lock);
+    vlc_interrupt_finish(ctx);
+    vlc_cond_destroy(cond);
+}
+
+int vlc_mwait_i11e(mtime_t deadline)
+{
+    vlc_interrupt_t *ctx = vlc_threadvar_get(vlc_interrupt_var);
+    if (ctx == NULL)
+        return mwait(deadline), 0;
+
+    vlc_cond_t wait;
+    vlc_cond_init(&wait);
+
+    int ret = vlc_interrupt_prepare(ctx, vlc_mwait_i11e_wake, &wait);
+    if (ret)
+    {
+        vlc_cond_destroy(&wait);
+        vlc_testcancel();
+        return ret;
+    }
+
+    vlc_mutex_lock(&ctx->lock);
+    vlc_cleanup_push(vlc_mwait_i11e_cleanup, ctx);
+    while (!ctx->interrupted
+        && vlc_cond_timedwait(&wait, &ctx->lock, deadline) == 0);
+    vlc_cleanup_pop();
+    vlc_mutex_unlock(&ctx->lock);
+
+    ret = vlc_interrupt_finish(ctx);
+    vlc_cond_destroy(&wait);
+    return ret;
+}
+
 #ifndef _WIN32
 static void vlc_poll_i11e_wake(void *opaque)
 {



More information about the vlc-commits mailing list