brasero r1382 - in trunk: . src
- From: philippr svn gnome org
- To: svn-commits-list gnome org
- Subject: brasero r1382 - in trunk: . src
- Date: Wed, 15 Oct 2008 18:23:12 +0000 (UTC)
Author: philippr
Date: Wed Oct 15 18:23:12 2008
New Revision: 1382
URL: http://svn.gnome.org/viewvc/brasero?rev=1382&view=rev
Log:
Probe for medium asynchronously and avoid blocking sometimes
* src/burn-drive.c (brasero_drive_get_medium),
(brasero_drive_medium_probed), (brasero_drive_reprobe),
(brasero_drive_check_medium_inside):
* src/burn-drive.h:
* src/burn-medium.c (brasero_medium_get_sessions_info),
(brasero_medium_init_real), (brasero_medium_probed),
(brasero_medium_probe_thread), (brasero_medium_probe),
(brasero_medium_finalize), (brasero_medium_set_property),
(brasero_medium_class_init):
* src/burn-medium.h:
* src/burn.c (brasero_burn_record_session):
Modified:
trunk/ChangeLog
trunk/src/burn-drive.c
trunk/src/burn-drive.h
trunk/src/burn-medium.c
trunk/src/burn-medium.h
trunk/src/burn.c
Modified: trunk/src/burn-drive.c
==============================================================================
--- trunk/src/burn-drive.c (original)
+++ trunk/src/burn-drive.c Wed Oct 15 18:23:12 2008
@@ -65,6 +65,8 @@
gint lun;
gulong hal_sig;
+
+ guint probed:1;
};
#define BRASERO_DRIVE_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), BRASERO_TYPE_DRIVE, BraseroDrivePrivate))
@@ -288,6 +290,10 @@
return NULL;
priv = BRASERO_DRIVE_PRIVATE (self);
+
+ if (!priv->probed && priv->udi)
+ return NULL;
+
return priv->medium;
}
@@ -365,6 +371,56 @@
}
static void
+brasero_drive_medium_probed (BraseroMedium *medium,
+ BraseroDrive *self)
+{
+ BraseroDrivePrivate *priv;
+
+ priv = BRASERO_DRIVE_PRIVATE (self);
+
+ /* only when it is probed */
+ priv->probed = TRUE;
+ g_signal_emit (self,
+ drive_signals [MEDIUM_INSERTED],
+ 0,
+ priv->medium);
+}
+
+void
+brasero_drive_reprobe (BraseroDrive *self)
+{
+ BraseroDrivePrivate *priv;
+ BraseroMedium *medium;
+
+ priv = BRASERO_DRIVE_PRIVATE (self);
+
+ if (!priv->medium)
+ return;
+
+ BRASERO_BURN_LOG ("Reprobing inserted medium");
+
+ /* remove current medium */
+ medium = priv->medium;
+ priv->medium = NULL;
+
+ g_signal_emit (self,
+ drive_signals [MEDIUM_REMOVED],
+ 0,
+ medium);
+ g_object_unref (medium);
+ priv->probed = FALSE;
+
+ /* try to get a new one */
+ priv->medium = g_object_new (BRASERO_TYPE_VOLUME,
+ "drive", self,
+ NULL);
+ g_signal_connect (priv->medium,
+ "probed",
+ G_CALLBACK (brasero_drive_medium_probed),
+ self);
+}
+
+static void
brasero_drive_check_medium_inside (BraseroDrive *self)
{
BraseroDrivePrivate *priv;
@@ -393,16 +449,17 @@
}
if (has_medium) {
- BRASERO_BURN_LOG ("New medium inserted");
+ BRASERO_BURN_LOG ("Medium inserted");
+ priv->probed = FALSE;
priv->medium = g_object_new (BRASERO_TYPE_VOLUME,
"drive", self,
NULL);
- if (priv->medium)
- g_signal_emit (self,
- drive_signals [MEDIUM_INSERTED],
- 0,
- priv->medium);
+
+ g_signal_connect (priv->medium,
+ "probed",
+ G_CALLBACK (brasero_drive_medium_probed),
+ self);
}
else if (priv->medium) {
BraseroMedium *medium;
@@ -417,6 +474,7 @@
0,
medium);
g_object_unref (medium);
+ priv->probed = FALSE;
}
}
Modified: trunk/src/burn-drive.h
==============================================================================
--- trunk/src/burn-drive.h (original)
+++ trunk/src/burn-drive.h Wed Oct 15 18:23:12 2008
@@ -68,6 +68,9 @@
BraseroDrive *
brasero_drive_new (const gchar *udi);
+void
+brasero_drive_reprobe (BraseroDrive *drive);
+
BraseroMedium *
brasero_drive_get_medium (BraseroDrive *drive);
Modified: trunk/src/burn-medium.c
==============================================================================
--- trunk/src/burn-medium.c (original)
+++ trunk/src/burn-medium.c Wed Oct 15 18:23:12 2008
@@ -28,6 +28,7 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
+#include <unistd.h>
#include <glib.h>
#include <glib/gi18n-lib.h>
@@ -88,7 +89,8 @@
typedef struct _BraseroMediumPrivate BraseroMediumPrivate;
struct _BraseroMediumPrivate
{
- gint retry_id;
+ GThread *probe;
+ gint probe_id;
GSList *tracks;
@@ -118,6 +120,8 @@
guint dummy_sao:2;
guint dummy_tao:2;
guint burnfree:2;
+
+ guint probe_cancelled:1;
};
#define BRASERO_MEDIUM_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), BRASERO_TYPE_MEDIUM, BraseroMediumPrivate))
@@ -137,6 +141,14 @@
PROP_DRIVE,
};
+enum {
+ PROBED,
+ LAST_SIGNAL
+};
+static gulong medium_signals [LAST_SIGNAL] = {0, };
+
+#define BRASERO_MEDIUM_OPEN_ATTEMPTS 5
+
static GObjectClass* parent_class = NULL;
gchar *
@@ -1750,6 +1762,11 @@
continue;
}
+ if (priv->probe_cancelled) {
+ g_free (toc);
+ return BRASERO_BURN_CANCEL;
+ }
+
brasero_medium_track_get_info (self,
multisession,
track,
@@ -1758,6 +1775,11 @@
code);
}
+ if (priv->probe_cancelled) {
+ g_free (toc);
+ return BRASERO_BURN_CANCEL;
+ }
+
/* put the tracks in the right order */
priv->tracks = g_slist_reverse (priv->tracks);
@@ -2815,27 +2837,45 @@
BRASERO_BURN_LOG ("Initializing information for medium in %s", name);
g_free (name);
+ if (priv->probe_cancelled)
+ return;
+
result = brasero_medium_get_medium_type (object, handle, &code);
if (result != BRASERO_BURN_OK)
return;
+ if (priv->probe_cancelled)
+ return;
+
brasero_medium_get_capacity_by_type (object, handle, &code);
result = brasero_medium_get_contents (object, handle, &code);
if (result != BRASERO_BURN_OK)
return;
+ if (priv->probe_cancelled)
+ return;
+
/* assume that css feature is only for DVD-ROM which might be wrong but
* some drives wrongly reports that css is enabled for blank DVD+R/W */
if (BRASERO_MEDIUM_IS (priv->info, (BRASERO_MEDIUM_DVD|BRASERO_MEDIUM_ROM)))
brasero_medium_get_css_feature (object, handle, &code);
+ if (priv->probe_cancelled)
+ return;
+
brasero_medium_init_caps (object, handle, &code);
+ if (priv->probe_cancelled)
+ return;
+
/* read CD-TEXT title */
if (priv->info & BRASERO_MEDIUM_HAS_AUDIO)
brasero_medium_read_CD_TEXT (object, handle, &code);
+ if (priv->probe_cancelled)
+ return;
+
BRASERO_BURN_LOG_DISC_TYPE (priv->info, "media is ");
if (!priv->wr_speeds)
@@ -2858,48 +2898,25 @@
}
static gboolean
-brasero_medium_retry_open (gpointer object)
+brasero_medium_probed (gpointer data)
{
- const gchar *path;
- BraseroMedium *self;
- BraseroScsiErrCode code;
BraseroMediumPrivate *priv;
- BraseroDeviceHandle *handle;
- self = BRASERO_MEDIUM (object);
- priv = BRASERO_MEDIUM_PRIVATE (object);
- path = brasero_drive_get_device (priv->drive);
+ priv = BRASERO_MEDIUM_PRIVATE (data);
- BRASERO_BURN_LOG ("Retrying to open device %s", path);
- handle = brasero_device_handle_open (path, &code);
- if (!handle) {
- if (code == BRASERO_SCSI_NOT_READY) {
- BRASERO_BURN_LOG ("Device busy");
- /* we'll retry in a second */
- return TRUE;
- }
-
- BRASERO_BURN_LOG ("Open () failed");
- priv->info = BRASERO_MEDIUM_UNSUPPORTED;
- priv->retry_id = 0;
- return FALSE;
- }
-
- BRASERO_BURN_LOG ("Open () succeeded\n");
- priv->info = BRASERO_MEDIUM_NONE;
- priv->icon = icons [0];
-
- priv->retry_id = 0;
-
- brasero_medium_init_real (self, handle);
- brasero_device_handle_close (handle);
+ /* This signal must be emitted in the main thread */
+ g_signal_emit (data,
+ medium_signals [PROBED],
+ 0);
+ priv->probe_id = 0;
return FALSE;
}
-static void
-brasero_medium_try_open (BraseroMedium *self)
+static gpointer
+brasero_medium_probe_thread (gpointer self)
{
+ gint counter = 0;
const gchar *path;
BraseroScsiErrCode code;
BraseroMediumPrivate *priv;
@@ -2908,75 +2925,60 @@
priv = BRASERO_MEDIUM_PRIVATE (self);
path = brasero_drive_get_device (priv->drive);
+ priv->info = BRASERO_MEDIUM_BUSY;
+ priv->icon = icons [0];
+
/* the drive might be busy (a burning is going on) so we don't block
* but we re-try to open it every second */
BRASERO_BURN_LOG ("Trying to open device %s", path);
+
handle = brasero_device_handle_open (path, &code);
+ while (!handle && counter <= BRASERO_MEDIUM_OPEN_ATTEMPTS) {
+ sleep (1);
- if (!handle) {
- if (code == BRASERO_SCSI_NOT_READY) {
- BRASERO_BURN_LOG ("Device busy");
- priv->info = BRASERO_MEDIUM_BUSY;
- priv->icon = icons [0];
-
- priv->retry_id = g_timeout_add (BUSY_RETRY_TIME,
- brasero_medium_retry_open,
- self);
+ if (priv->probe_cancelled) {
+ priv->probe = NULL;
+ return NULL;
}
- BRASERO_BURN_LOG ("Open () failed");
- return;
+ counter ++;
+ handle = brasero_device_handle_open (path, &code);
}
- BRASERO_BURN_LOG ("Open () succeeded");
- brasero_medium_init_real (self, handle);
- brasero_device_handle_close (handle);
-}
-
-void
-brasero_medium_reload_info (BraseroMedium *self)
-{
- BraseroMediumPrivate *priv;
-
- g_return_if_fail (BRASERO_IS_MEDIUM (self));
-
- priv = BRASERO_MEDIUM_PRIVATE (self);
-
- priv->max_rd = 0;
- priv->max_wrt = 0;
- priv->block_num = 0;
- priv->block_size = 0;
- priv->next_wr_add = -1;
- priv->type = NULL;
- priv->icon = NULL;
- priv->info = BRASERO_MEDIUM_NONE;
-
- if (priv->retry_id) {
- g_source_remove (priv->retry_id);
- priv->retry_id = 0;
+ if (priv->probe_cancelled) {
+ priv->probe = NULL;
+ return NULL;
}
- if (priv->id) {
- g_free (priv->id);
- priv->id = NULL;
- }
-
- if (priv->CD_TEXT_title) {
- g_free (priv->CD_TEXT_title);
- priv->CD_TEXT_title = NULL;
+ if (handle) {
+ BRASERO_BURN_LOG ("Open () succeeded");
+ brasero_medium_init_real (BRASERO_MEDIUM (self), handle);
+ brasero_device_handle_close (handle);
}
+ else
+ BRASERO_BURN_LOG ("Open () failed: medium busy");
- g_free (priv->rd_speeds);
- priv->rd_speeds = NULL;
+ priv->probe_id = g_idle_add (brasero_medium_probed, self);
+ priv->probe = NULL;
+ return NULL;
+}
- g_free (priv->wr_speeds);
- priv->wr_speeds = NULL;
+static void
+brasero_medium_probe (BraseroMedium *self)
+{
+ BraseroMediumPrivate *priv;
- g_slist_foreach (priv->tracks, (GFunc) g_free, NULL);
- g_slist_free (priv->tracks);
- priv->tracks = NULL;
+ priv = BRASERO_MEDIUM_PRIVATE (self);
- brasero_medium_try_open (self);
+ /* NOTE: why a thread? Because in case of a damaged medium, brasero can
+ * block on some functions until timeout and if we do this in the main
+ * 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. */
+ priv->probe = g_thread_create (brasero_medium_probe_thread,
+ self,
+ TRUE,
+ NULL);
}
static void
@@ -3009,9 +3011,15 @@
priv = BRASERO_MEDIUM_PRIVATE (object);
- if (priv->retry_id) {
- g_source_remove (priv->retry_id);
- priv->retry_id = 0;
+ if (priv->probe) {
+ priv->probe_cancelled = TRUE;
+ g_thread_join (priv->probe);
+ priv->probe = 0;
+ }
+
+ if (priv->probe_id) {
+ g_source_remove (priv->probe_id);
+ priv->probe_id = 0;
}
if (priv->id) {
@@ -3061,7 +3069,7 @@
break;
}
- brasero_medium_try_open (BRASERO_MEDIUM (object));
+ brasero_medium_probe (BRASERO_MEDIUM (object));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -3101,6 +3109,16 @@
object_class->set_property = brasero_medium_set_property;
object_class->get_property = brasero_medium_get_property;
+ medium_signals[PROBED] =
+ g_signal_new ("probed",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0,
+ G_TYPE_NONE);
+
g_object_class_install_property (object_class,
PROP_DRIVE,
g_param_spec_object ("drive",
Modified: trunk/src/burn-medium.h
==============================================================================
--- trunk/src/burn-medium.h (original)
+++ trunk/src/burn-medium.h Wed Oct 15 18:23:12 2008
@@ -91,8 +91,6 @@
};
typedef struct _BraseroMediumTrack BraseroMediumTrack;
-void
-brasero_medium_reload_info (BraseroMedium *self);
BraseroMedia
brasero_medium_get_status (BraseroMedium *medium);
Modified: trunk/src/burn.c
==============================================================================
--- trunk/src/burn.c (original)
+++ trunk/src/burn.c Wed Oct 15 18:23:12 2008
@@ -2114,21 +2114,19 @@
if (result != BRASERO_BURN_OK)
return result;
- medium = brasero_drive_get_medium (priv->dest);
- brasero_medium_reload_info (medium);
+ /* reprobe the medium and wait for it to be probed */
+ brasero_drive_reprobe (priv->dest);
+ while (!(medium = brasero_drive_get_medium (priv->dest)))
+ brasero_burn_sleep (burn, 1000);
if (type == BRASERO_CHECKSUM_MD5
|| type == BRASERO_CHECKSUM_SHA1
|| type == BRASERO_CHECKSUM_SHA256) {
BraseroMedia media;
- BraseroDrive *drive;
- BraseroMedium *medium;
/* get the last written track address in case of DVD+RW/DVD-RW
* restricted overwrite since there is no such thing as track
* number for these drives. */
- drive = brasero_burn_session_get_burner (priv->session);
- medium = brasero_drive_get_medium (drive);
media = brasero_medium_get_status (medium);
if (!BRASERO_MEDIUM_IS (media, BRASERO_MEDIUM_DVDRW_PLUS)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]