[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