[entangle] Fix crash when disconnecting from camera

Daniel P. Berrange berrange at fedoraproject.org
Tue Jun 28 13:12:15 UTC 2011


commit af3cc9facbb72d8c8fa0604bb62b5df64661ef0e
Author: Daniel P. Berrange <berrange at redhat.com>
Date:   Tue Jun 28 14:11:52 2011 +0100

    Fix crash when disconnecting from camera

 entangle-0.2.0-disconnect-crash.patch |  126 +++++++++++++++++++++++++++++++++
 entangle.spec                         |    7 ++-
 2 files changed, 132 insertions(+), 1 deletions(-)
---
diff --git a/entangle-0.2.0-disconnect-crash.patch b/entangle-0.2.0-disconnect-crash.patch
new file mode 100644
index 0000000..53c2a0a
--- /dev/null
+++ b/entangle-0.2.0-disconnect-crash.patch
@@ -0,0 +1,126 @@
+commit 3d81f114f4b5d7bb0bdd148e81f8978fa800ee3c
+Author: Daniel P. Berrange <dan at berrange.com>
+Date:   Fri Feb 4 23:02:52 2011 +0000
+
+    Avoid crash on camera disconnect
+    
+    The camera schedular thread make continue to run for a short
+    while after setting the 'quit' flag. Use a condition variable
+    to ensure we wait until it has shutdown before closing the
+    camera
+    
+    * backend/entangle-camera-scheduler.c: Wait for thread to finish
+      before returning
+    * frontend/entangle-camera-manager.c: Release GDK lock before
+      disconnecting camera to avoid deadlock
+
+diff --git a/src/backend/entangle-camera-scheduler.c b/src/backend/entangle-camera-scheduler.c
+index f6be120..182ade8 100644
+--- a/src/backend/entangle-camera-scheduler.c
++++ b/src/backend/entangle-camera-scheduler.c
+@@ -36,12 +36,14 @@ struct _EntangleCameraSchedulerPrivate {
+ 
+     GThread *worker;
+     GMutex *lock;
+-    gboolean cancelled;
+ 
++    gboolean quit;
+     gboolean pause;
+     gboolean resume;
++
+     GCond *pauseSignal;
+     GCond *resumeSignal;
++    GCond *quitSignal;
+ 
+     GAsyncQueue *tasks;
+ };
+@@ -185,6 +187,7 @@ static void entangle_camera_scheduler_init(EntangleCameraScheduler *scheduler)
+     priv->lock = g_mutex_new();
+     priv->pauseSignal = g_cond_new();
+     priv->resumeSignal = g_cond_new();
++    priv->quitSignal = g_cond_new();
+ }
+ 
+ 
+@@ -197,7 +200,7 @@ static gpointer entangle_camera_scheduler_worker(gpointer data)
+ 
+     g_mutex_lock(priv->lock);
+ 
+-    while (!priv->cancelled &&
++    while (!priv->quit &&
+            entangle_camera_get_connected(priv->camera)) {
+ 
+         g_mutex_unlock(priv->lock);
+@@ -257,6 +260,7 @@ static gpointer entangle_camera_scheduler_worker(gpointer data)
+ 
+     priv->worker = NULL;
+     g_mutex_unlock(priv->lock);
++    g_cond_signal(priv->quitSignal);
+ 
+     ENTANGLE_DEBUG("Camera scheduler worker done, purging tasks");
+     while (g_async_queue_length(priv->tasks) > 0) {
+@@ -274,20 +278,27 @@ gboolean entangle_camera_scheduler_start(EntangleCameraScheduler *scheduler)
+ {
+     EntangleCameraSchedulerPrivate *priv = scheduler->priv;
+ 
+-    if (priv->worker)
++    g_mutex_lock(priv->lock);
++
++    if (priv->worker) {
++        g_mutex_unlock(priv->lock);
+         return FALSE;
++    }
+ 
+     /* Keep a extra ref while the BG thread is active */
+     g_object_ref(scheduler);
+ 
+-    priv->cancelled = FALSE;
++    priv->quit = FALSE;
+     priv->worker = g_thread_create(entangle_camera_scheduler_worker,
+                                    scheduler,
+                                    FALSE,
+                                    NULL);
+-    if (!priv->worker)
++    if (!priv->worker) {
++        g_mutex_unlock(priv->lock);
+         return FALSE;
++    }
+ 
++    g_mutex_unlock(priv->lock);
+     return TRUE;
+ }
+ 
+@@ -296,11 +307,16 @@ gboolean entangle_camera_scheduler_end(EntangleCameraScheduler *scheduler)
+ {
+     EntangleCameraSchedulerPrivate *priv = scheduler->priv;
+ 
+-    if (!priv->worker)
++    g_mutex_lock(priv->lock);
++    if (!priv->worker) {
++        g_mutex_unlock(priv->lock);
+         return FALSE;
++    }
++
++    priv->quit = TRUE;
++    while (priv->worker != NULL)
++        g_cond_wait(priv->quitSignal, priv->lock);
+ 
+-    g_mutex_lock(priv->lock);
+-    priv->cancelled = TRUE;
+     g_mutex_unlock(priv->lock);
+ 
+     return TRUE;
+diff --git a/src/frontend/entangle-camera-manager.c b/src/frontend/entangle-camera-manager.c
+index ee14370..74902bc 100644
+--- a/src/frontend/entangle-camera-manager.c
++++ b/src/frontend/entangle-camera-manager.c
+@@ -597,7 +597,9 @@ static void do_remove_camera(EntangleCameraManager *manager)
+     g_signal_handler_disconnect(priv->scheduler, priv->sigTaskBegin);
+     g_signal_handler_disconnect(priv->scheduler, priv->sigTaskEnd);
+ 
++    gdk_threads_leave();
+     entangle_camera_scheduler_end(priv->scheduler);
++    gdk_threads_enter();
+     g_object_unref(priv->scheduler);
+     g_object_unref(priv->session);
+     priv->scheduler = NULL;
diff --git a/entangle.spec b/entangle.spec
index f6fff3b..98d842c 100644
--- a/entangle.spec
+++ b/entangle.spec
@@ -11,12 +11,13 @@
 Summary: Tethered shooting & control of digital cameras
 Name: entangle
 Version: 0.2.0
-Release: 5%{?dist}
+Release: 6%{?dist}
 License: GPLv3+
 Group: Applications/Multimedia
 Source: http://entangle-photo.org/download/sources/%{name}-%{version}.tar.gz
 Patch1: %{name}-%{version}-controls-empty.patch
 Patch2: %{name}-%{version}-sealed.patch
+Patch3: %{name}-%{version}-disconnect-crash.patch
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
 URL: http://entangle-photo.org/
 
@@ -56,6 +57,7 @@ and 'hands off' shooting directly from the controlling computer.
 %setup -q
 %patch1 -p1
 %patch2 -p1
+%patch3 -p1
 
 %build
 
@@ -120,6 +122,9 @@ update-desktop-database %{_datadir}/applications
 %endif
 
 %changelog
+* Tue Jun 28 2011 Daniel P. Berrange <berrange at redhat.com> - 0.2.0-6
+- Fix crash when disconnecting from camera
+
 * Mon Jun 27 2011 Daniel P Berrange <berrange at acer1810.home.berrange.com> - 0.2.0-5
 - Temporarily disable introspection/plugins since it now requires to GTK3
 


More information about the scm-commits mailing list