From 35de87cc583b47fc0f7349554214804e9a37446d Mon Sep 17 00:00:00 2001 From: Matthias Vogelgesang Date: Thu, 13 Nov 2014 12:15:53 +0100 Subject: Fix #61 causing a race condition The buffer thread now waits on the *intent* to stop the recording (i.e. the internal state) instead of using the external state information. --- src/uca-camera.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/uca-camera.c b/src/uca-camera.c index bd9c437..2de1489 100644 --- a/src/uca-camera.c +++ b/src/uca-camera.c @@ -129,6 +129,7 @@ static GParamSpec *camera_properties[N_BASE_PROPERTIES] = { NULL, }; static GStaticMutex access_lock = G_STATIC_MUTEX_INIT; struct _UcaCameraPrivate { + gboolean cancelling_recording; gboolean is_recording; gboolean is_readout; gboolean transfer_async; @@ -553,6 +554,7 @@ uca_camera_init (UcaCamera *camera) camera->grab_func = NULL; camera->priv = UCA_CAMERA_GET_PRIVATE(camera); + camera->priv->cancelling_recording = FALSE; camera->priv->is_recording = FALSE; camera->priv->is_readout = FALSE; camera->priv->transfer_async = FALSE; @@ -600,7 +602,7 @@ buffer_thread (UcaCamera *camera) klass = UCA_CAMERA_GET_CLASS (camera); - while (camera->priv->is_recording) { + while (!camera->priv->cancelling_recording) { gpointer buffer; buffer = uca_ring_buffer_get_write_pointer (camera->priv->ring_buffer); @@ -661,6 +663,8 @@ uca_camera_start_recording (UcaCamera *camera, GError **error) if (tmp_error == NULL) { priv->is_readout = FALSE; priv->is_recording = TRUE; + priv->cancelling_recording = FALSE; + /* TODO: we should depend on GLib 2.26 and use g_object_notify_by_pspec */ g_object_notify (G_OBJECT (camera), "is-recording"); } @@ -721,7 +725,7 @@ uca_camera_stop_recording (UcaCamera *camera, GError **error) goto error_stop_recording; } - priv->is_recording = FALSE; + priv->cancelling_recording = TRUE; if (priv->buffered) { g_thread_join (priv->read_thread); @@ -729,10 +733,14 @@ uca_camera_stop_recording (UcaCamera *camera, GError **error) } g_static_mutex_lock (&access_lock); + (*klass->stop_recording)(camera, &tmp_error); + priv->cancelling_recording = FALSE; + g_static_mutex_unlock (&access_lock); if (tmp_error == NULL) { + priv->is_recording = FALSE; priv->is_readout = FALSE; /* TODO: we should depend on GLib 2.26 and use g_object_notify_by_pspec */ g_object_notify (G_OBJECT (camera), "is-recording"); -- cgit v1.2.3