[vlc-commits] win32: Inhibit: Call SetThreadExecutionState from a dedicated thread
Hugo Beauzée-Luyssen
git at videolan.org
Wed Jan 24 21:08:13 CET 2018
vlc | branch: master | Hugo Beauzée-Luyssen <hugo at beauzee.fr> | Wed Jan 24 17:52:23 2018 +0100| [b2ea8558193cd6aa07da36a2e5eab7f8d846eb33] | committer: Hugo Beauzée-Luyssen
win32: Inhibit: Call SetThreadExecutionState from a dedicated thread
Fix #19463
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=b2ea8558193cd6aa07da36a2e5eab7f8d846eb33
---
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