Mauro Carvalho Chehab f68a82b
From 3e2e3deed8dceb6b72bb2318b65d816197a30801 Mon Sep 17 00:00:00 2001
Mauro Carvalho Chehab f68a82b
From: Mauro Carvalho Chehab <mchehab@kernel.org>
Mauro Carvalho Chehab f68a82b
Date: Thu, 24 Mar 2022 17:59:11 +0100
Mauro Carvalho Chehab f68a82b
Subject: [PATCH] Prevent crashes on device changes with control window opened
Mauro Carvalho Chehab f68a82b
Mauro Carvalho Chehab f68a82b
Changing the device without closing the control window
Mauro Carvalho Chehab f68a82b
will cause crashes, as the newer device will very likely have
Mauro Carvalho Chehab f68a82b
different settings.
Mauro Carvalho Chehab f68a82b
Mauro Carvalho Chehab f68a82b
Protect any changes at the camera control window with a
Mauro Carvalho Chehab f68a82b
mutex and close the control window on a safe way, on
Mauro Carvalho Chehab f68a82b
device changes.
Mauro Carvalho Chehab f68a82b
Mauro Carvalho Chehab f68a82b
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Mauro Carvalho Chehab f68a82b
Mauro Carvalho Chehab f68a82b
diff --git a/src/callbacks.c b/src/callbacks.c
Mauro Carvalho Chehab f68a82b
index 3cd5222bb51d..a7a6b528e72a 100644
Mauro Carvalho Chehab f68a82b
--- a/src/callbacks.c
Mauro Carvalho Chehab f68a82b
+++ b/src/callbacks.c
Mauro Carvalho Chehab f68a82b
@@ -870,7 +870,9 @@ static void reset_ctrls(GtkButton *btn, cam_t *cam)
Mauro Carvalho Chehab f68a82b
 
Mauro Carvalho Chehab f68a82b
 static void close_controls(GtkWidget* widget, cam_t *cam)
Mauro Carvalho Chehab f68a82b
 {
Mauro Carvalho Chehab f68a82b
+    g_mutex_lock(&cam->control_win_mutex);
Mauro Carvalho Chehab f68a82b
     cam->controls_window = NULL;
Mauro Carvalho Chehab f68a82b
+    g_mutex_unlock(&cam->control_win_mutex);
Mauro Carvalho Chehab f68a82b
 }
Mauro Carvalho Chehab f68a82b
 
Mauro Carvalho Chehab f68a82b
 void show_controls(GtkWidget *widget, cam_t *cam)
Mauro Carvalho Chehab f68a82b
@@ -982,7 +984,9 @@ void show_controls(GtkWidget *widget, cam_t *cam)
Mauro Carvalho Chehab f68a82b
     g_signal_connect(G_OBJECT(window), "destroy",
Mauro Carvalho Chehab f68a82b
                      G_CALLBACK (close_controls), cam);
Mauro Carvalho Chehab f68a82b
 
Mauro Carvalho Chehab f68a82b
+    g_mutex_lock(&cam->control_win_mutex);
Mauro Carvalho Chehab f68a82b
     cam->controls_window = window;
Mauro Carvalho Chehab f68a82b
+    g_mutex_unlock(&cam->control_win_mutex);
Mauro Carvalho Chehab f68a82b
 
Mauro Carvalho Chehab f68a82b
     gtk_widget_show_all(window);
Mauro Carvalho Chehab f68a82b
 }
Mauro Carvalho Chehab f68a82b
@@ -1150,8 +1154,10 @@ void contrast_change(GtkScale *sc1, cam_t *cam)
Mauro Carvalho Chehab f68a82b
     cam->contrast = gtk_range_get_value((GtkRange *) sc1);
Mauro Carvalho Chehab f68a82b
     cam_set_control(cam, V4L2_CID_CONTRAST, &cam->contrast);
Mauro Carvalho Chehab f68a82b
 
Mauro Carvalho Chehab f68a82b
+    g_mutex_lock(&cam->control_win_mutex);
Mauro Carvalho Chehab f68a82b
     if (cam->controls_window)
Mauro Carvalho Chehab f68a82b
         gtk_container_forall(GTK_CONTAINER(cam->controls_window), send_update_signal, 0);
Mauro Carvalho Chehab f68a82b
+    g_mutex_unlock(&cam->control_win_mutex);
Mauro Carvalho Chehab f68a82b
 }
Mauro Carvalho Chehab f68a82b
 
Mauro Carvalho Chehab f68a82b
 void brightness_change(GtkScale *sc1, cam_t *cam)
Mauro Carvalho Chehab f68a82b
@@ -1160,8 +1166,10 @@ void brightness_change(GtkScale *sc1, cam_t *cam)
Mauro Carvalho Chehab f68a82b
     cam->brightness = gtk_range_get_value((GtkRange *) sc1);
Mauro Carvalho Chehab f68a82b
     cam_set_control(cam, V4L2_CID_BRIGHTNESS, &cam->brightness);
Mauro Carvalho Chehab f68a82b
 
Mauro Carvalho Chehab f68a82b
+    g_mutex_lock(&cam->control_win_mutex);
Mauro Carvalho Chehab f68a82b
     if (cam->controls_window)
Mauro Carvalho Chehab f68a82b
         gtk_container_forall(GTK_CONTAINER(cam->controls_window), send_update_signal, 0);
Mauro Carvalho Chehab f68a82b
+    g_mutex_unlock(&cam->control_win_mutex);
Mauro Carvalho Chehab f68a82b
 }
Mauro Carvalho Chehab f68a82b
 
Mauro Carvalho Chehab f68a82b
 void zoom_change(GtkScale *sc1, cam_t *cam)
Mauro Carvalho Chehab f68a82b
@@ -1180,8 +1188,10 @@ void colour_change(GtkScale *sc1, cam_t *cam)
Mauro Carvalho Chehab f68a82b
     cam->colour = gtk_range_get_value((GtkRange *) sc1);
Mauro Carvalho Chehab f68a82b
     cam_set_control(cam, V4L2_CID_SATURATION, &cam->colour);
Mauro Carvalho Chehab f68a82b
 
Mauro Carvalho Chehab f68a82b
+    g_mutex_lock(&cam->control_win_mutex);
Mauro Carvalho Chehab f68a82b
     if (cam->controls_window)
Mauro Carvalho Chehab f68a82b
         gtk_container_forall(GTK_CONTAINER(cam->controls_window), send_update_signal, 0);
Mauro Carvalho Chehab f68a82b
+    g_mutex_unlock(&cam->control_win_mutex);
Mauro Carvalho Chehab f68a82b
 }
Mauro Carvalho Chehab f68a82b
 
Mauro Carvalho Chehab f68a82b
 void hue_change(GtkScale *sc1, cam_t *cam)
Mauro Carvalho Chehab f68a82b
@@ -1190,8 +1200,10 @@ void hue_change(GtkScale *sc1, cam_t *cam)
Mauro Carvalho Chehab f68a82b
     cam->hue = gtk_range_get_value((GtkRange *) sc1);
Mauro Carvalho Chehab f68a82b
     cam_set_control(cam, V4L2_CID_HUE, &cam->hue);
Mauro Carvalho Chehab f68a82b
 
Mauro Carvalho Chehab f68a82b
+    g_mutex_lock(&cam->control_win_mutex);
Mauro Carvalho Chehab f68a82b
     if (cam->controls_window)
Mauro Carvalho Chehab f68a82b
         gtk_container_forall(GTK_CONTAINER(cam->controls_window), send_update_signal, 0);
Mauro Carvalho Chehab f68a82b
+    g_mutex_unlock(&cam->control_win_mutex);
Mauro Carvalho Chehab f68a82b
 }
Mauro Carvalho Chehab f68a82b
 
Mauro Carvalho Chehab f68a82b
 void wb_change(GtkScale *sc1, cam_t *cam)
Mauro Carvalho Chehab f68a82b
@@ -1200,8 +1212,10 @@ void wb_change(GtkScale *sc1, cam_t *cam)
Mauro Carvalho Chehab f68a82b
     cam->whiteness = gtk_range_get_value((GtkRange *) sc1);
Mauro Carvalho Chehab f68a82b
     cam_set_control(cam, V4L2_CID_WHITENESS, &cam->whiteness);
Mauro Carvalho Chehab f68a82b
 
Mauro Carvalho Chehab f68a82b
+    g_mutex_lock(&cam->control_win_mutex);
Mauro Carvalho Chehab f68a82b
     if (cam->controls_window)
Mauro Carvalho Chehab f68a82b
         gtk_container_forall(GTK_CONTAINER(cam->controls_window), send_update_signal, 0);
Mauro Carvalho Chehab f68a82b
+    g_mutex_unlock(&cam->control_win_mutex);
Mauro Carvalho Chehab f68a82b
 }
Mauro Carvalho Chehab f68a82b
 
Mauro Carvalho Chehab f68a82b
 /*
Mauro Carvalho Chehab f68a82b
@@ -1409,6 +1423,7 @@ int select_video_dev(cam_t *cam)
Mauro Carvalho Chehab f68a82b
 
Mauro Carvalho Chehab f68a82b
 void on_change_camera(GtkWidget *widget, cam_t *cam)
Mauro Carvalho Chehab f68a82b
 {
Mauro Carvalho Chehab f68a82b
+    GtkWidget *window;
Mauro Carvalho Chehab f68a82b
     gchar *old_cam;
Mauro Carvalho Chehab f68a82b
 
Mauro Carvalho Chehab f68a82b
     old_cam = g_strdup(cam->video_dev);
Mauro Carvalho Chehab f68a82b
@@ -1421,6 +1436,16 @@ void on_change_camera(GtkWidget *widget, cam_t *cam)
Mauro Carvalho Chehab f68a82b
     }
Mauro Carvalho Chehab f68a82b
     g_free(old_cam);
Mauro Carvalho Chehab f68a82b
 
Mauro Carvalho Chehab f68a82b
+    g_mutex_lock(&cam->control_win_mutex);
Mauro Carvalho Chehab f68a82b
+    if (cam->controls_window) {
Mauro Carvalho Chehab f68a82b
+        window = cam->controls_window;
Mauro Carvalho Chehab f68a82b
+        cam->controls_window = NULL;
Mauro Carvalho Chehab f68a82b
+        g_mutex_unlock(&cam->control_win_mutex);
Mauro Carvalho Chehab f68a82b
+        gtk_window_close(GTK_WINDOW(window));
Mauro Carvalho Chehab f68a82b
+    } else {
Mauro Carvalho Chehab f68a82b
+        g_mutex_unlock(&cam->control_win_mutex);
Mauro Carvalho Chehab f68a82b
+    }
Mauro Carvalho Chehab f68a82b
+
Mauro Carvalho Chehab f68a82b
     start_camera(cam);
Mauro Carvalho Chehab f68a82b
     update_sliders(cam);
Mauro Carvalho Chehab f68a82b
 }
Mauro Carvalho Chehab f68a82b
diff --git a/src/main.c b/src/main.c
Mauro Carvalho Chehab f68a82b
index 2f18136086d8..d8ef8b868f94 100644
Mauro Carvalho Chehab f68a82b
--- a/src/main.c
Mauro Carvalho Chehab f68a82b
+++ b/src/main.c
Mauro Carvalho Chehab f68a82b
@@ -107,6 +107,7 @@ static void activate(GtkApplication *app)
Mauro Carvalho Chehab f68a82b
     cam->app = app;
Mauro Carvalho Chehab f68a82b
     g_mutex_init(&cam->remote_save_mutex);
Mauro Carvalho Chehab f68a82b
     g_mutex_init(&cam->pixbuf_mutex);
Mauro Carvalho Chehab f68a82b
+    g_mutex_init(&cam->control_win_mutex);
Mauro Carvalho Chehab f68a82b
 
Mauro Carvalho Chehab f68a82b
     /* gtk is initialized now */
Mauro Carvalho Chehab f68a82b
     camorama_filters_init();
Mauro Carvalho Chehab f68a82b
diff --git a/src/v4l.h b/src/v4l.h
Mauro Carvalho Chehab f68a82b
index d432e1564bb9..cc69875c280c 100644
Mauro Carvalho Chehab f68a82b
--- a/src/v4l.h
Mauro Carvalho Chehab f68a82b
+++ b/src/v4l.h
Mauro Carvalho Chehab f68a82b
@@ -103,6 +103,7 @@ typedef struct camera {
Mauro Carvalho Chehab f68a82b
 
Mauro Carvalho Chehab f68a82b
     GMutex remote_save_mutex;      /* Protects n_threads */
Mauro Carvalho Chehab f68a82b
     GMutex pixbuf_mutex;           /* Protects pic_buf */
Mauro Carvalho Chehab f68a82b
+    GMutex control_win_mutex;      /* Protects controls_window */
Mauro Carvalho Chehab f68a82b
 
Mauro Carvalho Chehab f68a82b
     unsigned int min_width, min_height, max_width, max_height;
Mauro Carvalho Chehab f68a82b
     struct colorspace_parms colorspc;