[brasero] Fix for #594417 - crashed with SIGSEGV in g_type_instance_get_private()
- From: Philippe Rouquier <philippr src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [brasero] Fix for #594417 - crashed with SIGSEGV in g_type_instance_get_private()
- Date: Tue, 8 Sep 2009 14:07:28 +0000 (UTC)
commit 81462010a71cd4fc5cea382c32bb9499546a224c
Author: Philippe Rouquier <bonfire-app wanadoo fr>
Date: Tue Sep 8 16:02:19 2009 +0200
Fix for #594417 - crashed with SIGSEGV in g_type_instance_get_private()
Fix for race condition
libbrasero-media/brasero-medium.c | 61 +++++++++++++++++++++++--------------
1 files changed, 38 insertions(+), 23 deletions(-)
---
diff --git a/libbrasero-media/brasero-medium.c b/libbrasero-media/brasero-medium.c
index 6a49145..402eb63 100644
--- a/libbrasero-media/brasero-medium.c
+++ b/libbrasero-media/brasero-medium.c
@@ -85,6 +85,8 @@ typedef struct _BraseroMediumPrivate BraseroMediumPrivate;
struct _BraseroMediumPrivate
{
GThread *probe;
+ GMutex *mutex;
+ GCond *cond;
gint probe_id;
GSList *tracks;
@@ -2925,12 +2927,11 @@ brasero_medium_probed (gpointer data)
{
BraseroMediumPrivate *priv;
+ g_return_val_if_fail (BRASERO_IS_MEDIUM (data), FALSE);
+
priv = BRASERO_MEDIUM_PRIVATE (data);
- if (priv->probe) {
- g_thread_join (priv->probe);
- priv->probe = NULL;
- }
+ priv->probe_id = 0;
/* This signal must be emitted in the main thread */
GDK_THREADS_ENTER ();
@@ -2939,7 +2940,6 @@ brasero_medium_probed (gpointer data)
0);
GDK_THREADS_LEAVE ();
- priv->probe_id = 0;
return FALSE;
}
@@ -2965,19 +2965,15 @@ brasero_medium_probe_thread (gpointer self)
while (!handle && counter <= BRASERO_MEDIUM_OPEN_ATTEMPTS) {
sleep (1);
- if (priv->probe_cancelled) {
- priv->probe = NULL;
- return NULL;
- }
+ if (priv->probe_cancelled)
+ goto end;
counter ++;
handle = brasero_device_handle_open (device, FALSE, &code);
}
- if (priv->probe_cancelled) {
- priv->probe = NULL;
- return NULL;
- }
+ if (priv->probe_cancelled)
+ goto end;
if (handle) {
BRASERO_MEDIA_LOG ("Open () succeeded");
@@ -2986,19 +2982,17 @@ brasero_medium_probe_thread (gpointer self)
* error code variable which is currently NULL */
while (brasero_spc1_test_unit_ready (handle, &code) != BRASERO_SCSI_OK) {
if (code != BRASERO_SCSI_NOT_READY) {
- priv->probe = NULL;
brasero_device_handle_close (handle);
BRASERO_MEDIA_LOG ("Device does not respond");
- break;
+ goto end;
}
sleep (2);
if (priv->probe_cancelled) {
- priv->probe = NULL;
brasero_device_handle_close (handle);
BRASERO_MEDIA_LOG ("Device probing cancelled");
- return NULL;
+ goto end;
}
}
@@ -3010,9 +3004,18 @@ brasero_medium_probe_thread (gpointer self)
else
BRASERO_MEDIA_LOG ("Open () failed: medium busy");
+end:
+
if (!priv->probe_cancelled)
priv->probe_id = g_idle_add (brasero_medium_probed, self);
+ g_mutex_lock (priv->mutex);
+ priv->probe = NULL;
+ g_cond_broadcast (priv->cond);
+ g_mutex_unlock (priv->mutex);
+
+ g_thread_exit (0);
+
return NULL;
}
@@ -3028,10 +3031,12 @@ brasero_medium_probe (BraseroMedium *self)
* thread then our whole UI blocks. This medium won't be exported by the
* BraseroDrive that exported until it returns PROBED signal.
* One (good) side effect is that it also improves start time. */
+ g_mutex_lock (priv->mutex);
priv->probe = g_thread_create (brasero_medium_probe_thread,
self,
TRUE,
NULL);
+ g_mutex_unlock (priv->mutex);
}
static void
@@ -3053,6 +3058,9 @@ brasero_medium_init (BraseroMedium *object)
priv = BRASERO_MEDIUM_PRIVATE (object);
priv->next_wr_add = -1;
+ priv->mutex = g_mutex_new ();
+ priv->cond = g_cond_new ();
+
/* we can't do anything here since properties haven't been set yet */
}
@@ -3065,21 +3073,28 @@ brasero_medium_finalize (GObject *object)
BRASERO_MEDIA_LOG ("Finalizing Medium object");
+ g_mutex_lock (priv->mutex);
if (priv->probe) {
- GThread *probe;
-
- probe = priv->probe;
priv->probe_cancelled = TRUE;
-
- g_thread_join (probe);
- priv->probe = NULL;
+ g_cond_wait (priv->cond, priv->mutex);
}
+ g_mutex_unlock (priv->mutex);
if (priv->probe_id) {
g_source_remove (priv->probe_id);
priv->probe_id = 0;
}
+ if (priv->mutex) {
+ g_mutex_free (priv->mutex);
+ priv->mutex = NULL;
+ }
+
+ if (priv->cond) {
+ g_cond_free (priv->cond);
+ priv->cond = NULL;
+ }
+
if (priv->id) {
g_free (priv->id);
priv->id = NULL;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]