[vlc-commits] video_output: handle the termination of the vout thread outside of control.c

Steve Lhomme git at videolan.org
Tue Jan 19 08:56:44 UTC 2021


vlc | branch: master | Steve Lhomme <robux4 at ycbcr.xyz> | Fri Dec 18 07:06:52 2020 +0100| [afe21dcfbb398a31cd4710aa2426018f6952269d] | committer: Steve Lhomme

video_output: handle the termination of the vout thread outside of control.c

To terminate the thread ASAP we need to set the terminate flag (from whatever
thread) and wake up the loop if it was waiting for anything.

The control_Pop still waits for the is_held to be false, meaning other threads
doing things on the vout to be done. This was done when the vout thread loop
was just receiving VOUT_CONTROL_TERMINATE to signify the end of the thread.

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

 src/video_output/control.c      | 19 ++-----------------
 src/video_output/control.h      |  4 +---
 src/video_output/video_output.c | 15 ++++++++++-----
 3 files changed, 13 insertions(+), 25 deletions(-)

diff --git a/src/video_output/control.c b/src/video_output/control.c
index 56f105f4bb..c5b14887ec 100644
--- a/src/video_output/control.c
+++ b/src/video_output/control.c
@@ -39,7 +39,6 @@ void vout_control_Init(vout_control_t *ctrl)
     ctrl->is_held = false;
     ctrl->is_waiting = false;
     ctrl->can_sleep = true;
-    ctrl->is_terminated = false;
     ARRAY_INIT(ctrl->cmd);
 }
 
@@ -65,14 +64,6 @@ void vout_control_Wake(vout_control_t *ctrl)
     vlc_mutex_unlock(&ctrl->lock);
 }
 
-void vout_control_PushTerminate(vout_control_t *ctrl)
-{
-    vlc_mutex_lock(&ctrl->lock);
-    ctrl->is_terminated = true;
-    vlc_cond_signal(&ctrl->wait_request);
-    vlc_mutex_unlock(&ctrl->lock);
-}
-
 void vout_control_Hold(vout_control_t *ctrl)
 {
     vlc_mutex_lock(&ctrl->lock);
@@ -91,13 +82,12 @@ void vout_control_Release(vout_control_t *ctrl)
     vlc_mutex_unlock(&ctrl->lock);
 }
 
-int vout_control_Pop(vout_control_t *ctrl, vlc_mouse_t *mouse,
-                     bool *is_terminated, vlc_tick_t deadline)
+int vout_control_Pop(vout_control_t *ctrl, vlc_mouse_t *mouse, vlc_tick_t deadline)
 {
     bool has_cmd = false;
     vlc_mutex_lock(&ctrl->lock);
 
-    if (ctrl->cmd.i_size <= 0 && !ctrl->is_terminated) {
+    if (ctrl->cmd.i_size <= 0) {
         /* Spurious wakeups are perfectly fine */
         if (deadline != VLC_TICK_INVALID && ctrl->can_sleep) {
             ctrl->is_waiting = true;
@@ -110,9 +100,6 @@ int vout_control_Pop(vout_control_t *ctrl, vlc_mouse_t *mouse,
     while (ctrl->is_held)
         vlc_cond_wait(&ctrl->wait_available, &ctrl->lock);
 
-    if (ctrl->is_terminated)
-        goto done;
-
     if (ctrl->cmd.i_size > 0) {
         has_cmd = true;
         *mouse = ARRAY_VAL(ctrl->cmd, 0);
@@ -120,8 +107,6 @@ int vout_control_Pop(vout_control_t *ctrl, vlc_mouse_t *mouse,
     } else {
         ctrl->can_sleep = true;
     }
-done:
-    *is_terminated = ctrl->is_terminated;
     vlc_mutex_unlock(&ctrl->lock);
 
     return has_cmd ? VLC_SUCCESS : VLC_EGENERIC;
diff --git a/src/video_output/control.h b/src/video_output/control.h
index ce2c480879..35e8aad652 100644
--- a/src/video_output/control.h
+++ b/src/video_output/control.h
@@ -35,7 +35,6 @@ typedef struct {
     bool can_sleep;
     bool is_waiting;
     bool is_held;
-    bool is_terminated;
     DECL_ARRAY(vlc_mouse_t) cmd;
 } vout_control_t;
 
@@ -45,12 +44,11 @@ void vout_control_Clean(vout_control_t *);
 
 /* controls outside of the vout thread */
 void vout_control_PushMouse(vout_control_t *, const vlc_mouse_t *);
-void vout_control_PushTerminate(vout_control_t *);
 void vout_control_Wake(vout_control_t *);
 void vout_control_Hold(vout_control_t *);
 void vout_control_Release(vout_control_t *);
 
 /* control inside of the vout thread */
-int vout_control_Pop(vout_control_t *, vlc_mouse_t *, bool *, vlc_tick_t deadline);
+int vout_control_Pop(vout_control_t *, vlc_mouse_t *, vlc_tick_t deadline);
 
 #endif
diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c
index ed6b2c1849..46da5c8464 100644
--- a/src/video_output/video_output.c
+++ b/src/video_output/video_output.c
@@ -118,6 +118,7 @@ typedef struct vout_thread_sys_t
 
     /* Thread & synchronization */
     vout_control_t  control;
+    atomic_bool     control_is_terminated; // shutdown the vout thread
     vlc_thread_t    thread;
 
     struct {
@@ -1898,14 +1899,14 @@ static void *Thread(void *object)
             deadline = VLC_TICK_INVALID;
         }
 
-        bool terminated = false;
         vlc_mouse_t video_mouse;
-        while (vout_control_Pop(&sys->control, &video_mouse, &terminated,
-                                deadline) == VLC_SUCCESS && !terminated) {
+        while (vout_control_Pop(&sys->control, &video_mouse, deadline) == VLC_SUCCESS) {
+            if (atomic_load(&sys->control_is_terminated))
+                break;
             ThreadProcessMouseState(vout, &video_mouse);
         }
 
-        if (terminated)
+        if (atomic_load(&sys->control_is_terminated))
             break;
 
         wait = ThreadDisplayPicture(vout, &deadline) != VLC_SUCCESS;
@@ -1970,7 +1971,9 @@ void vout_StopDisplay(vout_thread_t *vout)
 {
     vout_thread_sys_t *sys = VOUT_THREAD_TO_SYS(vout);
 
-    vout_control_PushTerminate(&sys->control);
+    atomic_store(&sys->control_is_terminated, true);
+    // wake up so it goes back to the loop that will detect the terminated state
+    vout_control_Wake(&sys->control);
     vlc_join(sys->thread, NULL);
 
     vout_ReleaseDisplay(sys);
@@ -2115,6 +2118,7 @@ vout_thread_t *vout_Create(vlc_object_t *object)
                spu_Create(vout, vout) : NULL;
 
     vout_control_Init(&sys->control);
+    atomic_init(&sys->control_is_terminated, false);
 
     sys->title.show     = var_InheritBool(vout, "video-title-show");
     sys->title.timeout  = var_InheritInteger(vout, "video-title-timeout");
@@ -2303,6 +2307,7 @@ int vout_Request(const vout_configuration_t *cfg, vlc_video_context *vctx, input
         vout_DisableWindow(vout);
         return -1;
     }
+    atomic_store(&sys->control_is_terminated, false);
     if (vlc_clone(&sys->thread, Thread, vout, VLC_THREAD_PRIORITY_OUTPUT)) {
         vout_ReleaseDisplay(vout);
         vout_DisableWindow(vout);



More information about the vlc-commits mailing list