[PATCH 1/2] core: Add synchronous version of grl_media_source_metadata() function



Most of Grilo functions are asynchronous.

But there are some cases, when user do not want to deal with asynchronous
stuff, that having the appropriate synchronous verison would be useful.

So this patch adds this sychronous version in grl_media_source_metadata() for
free. This means that plugin author should not worry about dealing with
synchronous versions of the calls; she just implemement the asynchronous one,
as usual. Grilo will use this asynchronous version to implement a synchronous
one over it.

While running grl_media_source_metadata_sync() function, all remaining events
and idle functions are still functions, so they will be received and executed
even when waiting for the operation to be completed.
---
 src/grl-media-source.c |   88 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/grl-media-source.h |    7 ++++
 2 files changed, 95 insertions(+), 0 deletions(-)

diff --git a/src/grl-media-source.c b/src/grl-media-source.c
index 0d6b887..664761d 100644
--- a/src/grl-media-source.c
+++ b/src/grl-media-source.c
@@ -139,6 +139,12 @@ struct MetadataRelayCb {
   GrlMediaSourceMetadataSpec *spec;
 };
 
+struct OperationAsyncCb {
+  gboolean complete;
+  gpointer data;
+  GError *error;
+};
+
 struct OperationState {
   gboolean cancelled;
   gboolean completed;
@@ -787,6 +793,24 @@ metadata_result_relay_cb (GrlMediaSource *source,
   g_free (mrc);
 }
 
+static void
+metadata_result_async_cb (GrlMediaSource *source,
+                          GrlMedia *media,
+                          gpointer user_data,
+                          const GError *error)
+{
+  struct OperationAsyncCb *oa = (struct OperationAsyncCb *) user_data;
+
+  g_debug ("metadata_result_async_cb");
+
+  if (error) {
+    oa->error = g_error_copy (error);
+  }
+
+  oa->data = media;
+  oa->complete = TRUE;
+}
+
 static gint
 compare_sorted_results (gconstpointer a, gconstpointer b)
 {
@@ -1086,6 +1110,22 @@ metadata_full_resolution_ctl_cb (GrlMediaSource *source,
   }
 }
 
+static void
+wait_for_async_operation_complete (struct OperationAsyncCb *oa)
+{
+  GMainLoop *ml;
+  GMainContext *mc;
+
+  ml = g_main_loop_new (NULL, TRUE);
+  mc = g_main_loop_get_context (ml);
+
+ while (!oa->complete) {
+    g_main_context_iteration (mc, TRUE);
+  }
+
+  g_main_loop_unref (ml);
+}
+
 /* ================ API ================ */
 
 /**
@@ -1582,6 +1622,54 @@ grl_media_source_metadata (GrlMediaSource *source,
   g_idle_add (metadata_idle, ms);
 }
 
+/**
+ * grl_media_source_metadata_sync:
+ * @source: a media source
+ * @media: a data transfer object
+ * @keys: the list of #GrlKeyID to request
+ * @flags: the resolution mode
+ * @error: a #GError, or @NULL
+ *
+ * This method is intended to fetch the requested keys of metadata of
+ * a given @media to the media source.
+ *
+ * This method is synchronous.
+ *
+ * Returns: the updated #GrlMedia
+ */
+GrlMedia *
+grl_media_source_metadata_sync (GrlMediaSource *source,
+                                GrlMedia *media,
+                                const GList *keys,
+                                GrlMetadataResolutionFlags flags,
+                                GError **error)
+{
+  struct OperationAsyncCb *oa;
+
+  oa = g_slice_new0 (struct OperationAsyncCb);
+
+  grl_media_source_metadata (source,
+                             media,
+                             keys,
+                             flags,
+                             metadata_result_async_cb,
+                             oa);
+
+  wait_for_async_operation_complete (oa);
+
+  if (oa->error) {
+    if (error) {
+      *error = oa->error;
+    } else {
+      g_error_free (oa->error);
+    }
+  }
+
+  g_slice_free (struct OperationAsyncCb, oa);
+
+  return media;
+}
+
 static GrlSupportedOps
 grl_media_source_supported_operations (GrlMetadataSource *metadata_source)
 {
diff --git a/src/grl-media-source.h b/src/grl-media-source.h
index ba24950..309108d 100644
--- a/src/grl-media-source.h
+++ b/src/grl-media-source.h
@@ -360,6 +360,13 @@ void grl_media_source_metadata (GrlMediaSource *source,
                                 GrlMediaSourceMetadataCb callback,
                                 gpointer user_data);
 
+GrlMedia *grl_media_source_metadata_sync (GrlMediaSource *source,
+                                          GrlMedia *media,
+                                          const GList *keys,
+                                          GrlMetadataResolutionFlags flags,
+                                          GError **error);
+
+
 void grl_media_source_store (GrlMediaSource *source,
                              GrlMediaBox *parent,
                              GrlMedia *media,
-- 
1.7.0.4



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