brasero r1121 - in trunk: . src



Author: philippr
Date: Tue Aug 19 12:29:28 2008
New Revision: 1121
URL: http://svn.gnome.org/viewvc/brasero?rev=1121&view=rev

Log:
	If there are 2 or more requests at the same time to retrieve metadata
	for the same URI with the same flags, then just use one metadata object
	search for all of them

	* src/brasero-io.c (brasero_io_get_metadata_info):
	* src/brasero-metadata.c (brasero_metadata_lock),
	(brasero_metadata_unlock), (brasero_metadata_try_lock),
	(brasero_metadata_get_uri), (brasero_metadata_get_flags),
	(brasero_metadata_init), (brasero_metadata_finalize):
	* src/brasero-metadata.h:


Modified:
   trunk/ChangeLog
   trunk/src/brasero-io.c
   trunk/src/brasero-metadata.c
   trunk/src/brasero-metadata.h

Modified: trunk/src/brasero-io.c
==============================================================================
--- trunk/src/brasero-io.c	(original)
+++ trunk/src/brasero-io.c	Tue Aug 19 12:29:28 2008
@@ -57,6 +57,7 @@
 
 	/* used for metadata */
 	GSList *metadatas;
+	GSList *metadata_running;
 
 	/* used to "buffer" some results returned by metadata.
 	 * It takes time to return metadata and it's not unusual
@@ -644,6 +645,7 @@
 	BraseroIOPrivate *priv;
 	const gchar *mime;
 	gboolean result;
+	GSList *iter;
 	GList *node;
 
 	if (g_cancellable_is_cancelled (cancel))
@@ -662,6 +664,38 @@
 
 	g_mutex_lock (priv->lock);
 
+	/* First see if a metadata is running with the same uri and the same
+	 * flags as us. In this case, acquire the lock and wait for the lock
+	 * to become available which will mean that it has finished
+	 * NOTE: since we will hold the lock another thread waiting to get 
+	 * an available metadata won't be able to have this one. */
+	for (iter = priv->metadata_running; iter; iter = iter->next) {
+		const gchar *metadata_uri;
+		BraseroMetadata *metadata_iter;
+		BraseroMetadataFlag metadata_flags;
+
+		metadata_iter = iter->data;
+		metadata_uri = brasero_metadata_get_uri (metadata_iter);
+		metadata_flags = brasero_metadata_get_flags (metadata_iter);
+
+		if (((flags & metadata_flags) == flags)
+		&&  !strcmp (uri, metadata_uri)) {
+			/* Found one: release the IO lock to let other threads
+			 * do what they need to do then lock the metadata lock
+			 * Let the thread that got the lock first move it back
+			 * to waiting queue */
+			BRASERO_BURN_LOG ("Already ongoing search for %s", uri);
+
+			metadata = metadata_iter;
+
+			g_mutex_unlock (priv->lock);
+			brasero_metadata_lock (metadata);
+			result = brasero_metadata_set_info (metadata, meta_info);
+			brasero_metadata_unlock (metadata);
+
+			return result;
+		}
+	}
 	/* Seek in the buffer if we have already explored these metadata. Check 
 	 * the info last modified time in case a result should be updated. */
 	node = g_queue_find_custom (priv->meta_buffer,
@@ -705,9 +739,16 @@
 			return FALSE;
 		}
 
-		if (priv->metadatas) {
-			metadata = priv->metadatas->data;
-			priv->metadatas = g_slist_remove (priv->metadatas, metadata);
+		for (iter = priv->metadatas; iter; iter = iter->next) {
+			BraseroMetadata *metadata_iter;
+
+			metadata_iter = iter->data;
+			if (brasero_metadata_try_lock (metadata_iter)) {
+				metadata = priv->metadatas->data;
+				priv->metadatas = g_slist_remove (priv->metadatas, metadata);
+				priv->metadata_running = g_slist_prepend (priv->metadata_running, metadata);
+				break;
+			}
 		}
 
 		g_mutex_unlock (priv->lock);
@@ -727,6 +768,11 @@
 
 	g_mutex_lock (priv->lock);
 
+	/* release the lock on the metadata in case another thread is waiting 
+	 * for this search result. That way that thread will be able to wake
+	 * up. */
+	brasero_metadata_unlock (metadata);
+
 	if (result) {
 		/* see if we should add it to the buffer */
 		if (meta_info->has_audio || meta_info->has_video) {
@@ -746,6 +792,7 @@
 		}
 	}
 
+	priv->metadata_running = g_slist_remove (priv->metadata_running, metadata);
 	priv->metadatas = g_slist_prepend (priv->metadatas, metadata);
 
 	g_mutex_unlock (priv->lock);

Modified: trunk/src/brasero-metadata.c
==============================================================================
--- trunk/src/brasero-metadata.c	(original)
+++ trunk/src/brasero-metadata.c	Tue Aug 19 12:29:28 2008
@@ -83,6 +83,9 @@
 	GMutex *mutex;
 	GCond *cond;
 
+	/* Used by threads */
+	GMutex *lock;
+
 	guint started:1;
 	guint moved_forward:1;
 	guint prev_level_mes:1;
@@ -1477,6 +1480,51 @@
 }
 
 void
+brasero_metadata_lock (BraseroMetadata *self)
+{
+	BraseroMetadataPrivate *priv;
+
+	priv = BRASERO_METADATA_PRIVATE (self);
+	g_mutex_lock (priv->lock);
+}
+
+void
+brasero_metadata_unlock (BraseroMetadata *self)
+{
+	BraseroMetadataPrivate *priv;
+
+	priv = BRASERO_METADATA_PRIVATE (self);
+	g_mutex_unlock (priv->lock);
+}
+
+gboolean
+brasero_metadata_try_lock (BraseroMetadata *self)
+{
+	BraseroMetadataPrivate *priv;
+
+	priv = BRASERO_METADATA_PRIVATE (self);
+	return g_mutex_trylock (priv->lock);
+}
+
+const gchar *
+brasero_metadata_get_uri (BraseroMetadata *self)
+{
+	BraseroMetadataPrivate *priv;
+
+	priv = BRASERO_METADATA_PRIVATE (self);
+	return priv->info?priv->info->uri:NULL;
+}
+
+BraseroMetadataFlag
+brasero_metadata_get_flags (BraseroMetadata *self)
+{
+	BraseroMetadataPrivate *priv;
+
+	priv = BRASERO_METADATA_PRIVATE (self);
+	return priv->flags;
+}
+
+void
 brasero_metadata_info_copy (BraseroMetadataInfo *dest,
 			    BraseroMetadataInfo *src)
 {
@@ -1556,6 +1604,7 @@
 
 	priv->cond = g_cond_new ();
 	priv->mutex = g_mutex_new ();
+	priv->lock = g_mutex_new ();
 }
 
 static void
@@ -1602,6 +1651,11 @@
 		priv->cond = NULL;
 	}
 
+	if (priv->lock) {
+		g_mutex_free (priv->lock);
+		priv->lock = NULL;
+	}
+
 	G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 

Modified: trunk/src/brasero-metadata.h
==============================================================================
--- trunk/src/brasero-metadata.h	(original)
+++ trunk/src/brasero-metadata.h	Tue Aug 19 12:29:28 2008
@@ -107,25 +107,33 @@
 brasero_metadata_cancel (BraseroMetadata *metadata);
 
 gboolean
-brasero_metadata_get_info_wait (BraseroMetadata *self,
+brasero_metadata_get_info_wait (BraseroMetadata *metadata,
 				GCancellable *cancel,
 				const gchar *uri,
 				BraseroMetadataFlag flags,
 				GError **error);
 
 gboolean
-brasero_metadata_get_info_sync (BraseroMetadata *meta,
-				const gchar *uri,
-				BraseroMetadataFlag flags,
-				GError **error);
-
-gboolean
-brasero_metadata_get_info_async (BraseroMetadata *meta,
+brasero_metadata_get_info_async (BraseroMetadata *metadata,
 				 const gchar *uri,
 				 BraseroMetadataFlag flags);
+void
+brasero_metadata_lock (BraseroMetadata *metadata);
+
+void
+brasero_metadata_unlock (BraseroMetadata *metadata);
+
+gboolean
+brasero_metadata_try_lock (BraseroMetadata *metadata);
+
+const gchar *
+brasero_metadata_get_uri (BraseroMetadata *metadata);
+
+BraseroMetadataFlag
+brasero_metadata_get_flags (BraseroMetadata *metadata);
 
 gboolean
-brasero_metadata_set_info (BraseroMetadata *meta,
+brasero_metadata_set_info (BraseroMetadata *metadata,
 			   BraseroMetadataInfo *info);
 
 #endif				/* METADATA_H */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]