[vlc-commits] win32: Inhibit: Call SetThreadExecutionState from a dedicated thread

Hugo Beauzée-Luyssen git at videolan.org
Thu Jan 25 18:02:45 CET 2018


vlc/vlc-3.0 | branch: master | Hugo Beauzée-Luyssen <hugo at beauzee.fr> | Wed Jan 24 17:52:23 2018 +0100| [a734685ee4ad516b0e80211b43c314bcd697651c] | committer: Jean-Baptiste Kempf

win32: Inhibit: Call SetThreadExecutionState from a dedicated thread

Fix #19463

(cherry picked from commit b2ea8558193cd6aa07da36a2e5eab7f8d846eb33)
Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>

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

 modules/video_output/win32/inhibit.c | 84 +++++++++++++++++++++++++++++++-----
 1 file changed, 74 insertions(+), 10 deletions(-)

diff --git a/modules/video_output/win32/inhibit.c b/modules/video_output/win32/inhibit.c
index 0bc71420fa..aae006daaa 100644
--- a/modules/video_output/win32/inhibit.c
+++ b/modules/video_output/win32/inhibit.c
@@ -27,31 +27,95 @@
 #include <vlc_common.h>
 #include <vlc_inhibit.h>
 #include <vlc_plugin.h>
+#include <assert.h>
 
 struct vlc_inhibit_sys
 {
-    EXECUTION_STATE  prev_state;
+    vlc_sem_t sem;
+    vlc_mutex_t mutex;
+    vlc_cond_t cond;
+    vlc_thread_t thread;
+    bool signaled;
+    unsigned int mask;
 };
 
 static void Inhibit (vlc_inhibit_t *ih, unsigned mask)
 {
     vlc_inhibit_sys_t *sys = ih->p_sys;
-    bool suspend = (mask & VLC_INHIBIT_DISPLAY) != 0;
-    if (suspend)
-        /* Prevent monitor from powering off */
-        sys->prev_state =
-                SetThreadExecutionState( ES_DISPLAY_REQUIRED | ES_SYSTEM_REQUIRED | ES_CONTINUOUS );
-    else
-        SetThreadExecutionState( sys->prev_state );
+    vlc_mutex_lock(&sys->mutex);
+    sys->mask = mask;
+    sys->signaled = true;
+    vlc_mutex_unlock(&sys->mutex);
+    vlc_cond_signal(&sys->cond);
+}
+
+static void* Run(void* obj)
+{
+    vlc_inhibit_t *ih = (vlc_inhibit_t*)obj;
+    vlc_inhibit_sys_t *sys = ih->p_sys;
+    EXECUTION_STATE prev_state = ES_CONTINUOUS;
+
+    vlc_sem_post(&sys->sem);
+    while (true)
+    {
+        unsigned int mask;
+
+        vlc_mutex_lock(&sys->mutex);
+        mutex_cleanup_push(&sys->mutex);
+        while (!sys->signaled)
+            vlc_cond_wait(&sys->cond, &sys->mutex);
+        mask = sys->mask;
+        sys->signaled = false;
+        vlc_mutex_unlock(&sys->mutex);
+        vlc_cleanup_pop();
+
+        bool suspend = (mask & VLC_INHIBIT_DISPLAY) != 0;
+        if (suspend)
+            /* Prevent monitor from powering off */
+            prev_state = SetThreadExecutionState( ES_DISPLAY_REQUIRED |
+                                                  ES_SYSTEM_REQUIRED |
+                                                  ES_CONTINUOUS );
+        else
+            SetThreadExecutionState( prev_state );
+    }
+    vlc_assert_unreachable();
+}
+
+static void CloseInhibit (vlc_object_t *obj)
+{
+    vlc_inhibit_t *ih = (vlc_inhibit_t*)obj;
+    vlc_inhibit_sys_t* sys = ih->p_sys;
+    vlc_cancel(sys->thread);
+    vlc_join(sys->thread, NULL);
+    vlc_cond_destroy(&sys->cond);
+    vlc_mutex_destroy(&sys->mutex);
+    vlc_sem_destroy(&sys->sem);
 }
 
 static int OpenInhibit (vlc_object_t *obj)
 {
     vlc_inhibit_t *ih = (vlc_inhibit_t *)obj;
-    ih->p_sys = vlc_obj_malloc(obj, sizeof(vlc_inhibit_sys_t));
+    vlc_inhibit_sys_t *sys = ih->p_sys =
+            vlc_obj_malloc(obj, sizeof(vlc_inhibit_sys_t));
     if (unlikely(ih->p_sys == NULL))
         return VLC_ENOMEM;
 
+    vlc_sem_init(&sys->sem, 0);
+    vlc_mutex_init(&sys->mutex);
+    vlc_cond_init(&sys->cond);
+    sys->signaled = false;
+
+    /* SetThreadExecutionState always needs to be called from the same thread */
+    if (vlc_clone(&sys->thread, Run, ih, VLC_THREAD_PRIORITY_LOW))
+    {
+        vlc_cond_destroy(&sys->cond);
+        vlc_mutex_destroy(&sys->mutex);
+        vlc_sem_destroy(&sys->sem);
+        return VLC_EGENERIC;
+    }
+
+    vlc_sem_wait(&sys->sem);
+
     ih->inhibit = Inhibit;
     return VLC_SUCCESS;
 }
@@ -62,5 +126,5 @@ vlc_module_begin ()
     set_category (CAT_ADVANCED)
     set_subcategory (SUBCAT_ADVANCED_MISC)
     set_capability ("inhibit", 10)
-    set_callbacks (OpenInhibit, NULL)
+    set_callbacks (OpenInhibit, CloseInhibit)
 vlc_module_end ()



More information about the vlc-commits mailing list