[PATCH] core: introduce grilo operations
- From: lionel g landwerlin linux intel com
- To: grilo-list gnome org
- Subject: [PATCH] core: introduce grilo operations
- Date: Thu, 16 Jun 2011 19:15:37 +0100
From: Lionel Landwerlin <lionel g landwerlin linux intel com>
There are several ways to make requests on grilo at the moment. You
can either use the MediaSource API (to find medias) or the
MetadataSource API (to find metadatas) or the Multiple API (to find
medias on a set of media sources). Currently MediaSource and
MetadataSource share the same API to cancel an operation, but the
Multiple API remains different.
This patch proposes to unify all the operations and allocate their ids
at only one place. This benefits the user by making the whole API
simpler (you no longer have to remember to how to cancel your
operation, there is only one way to do it).
This other advantage of this patch is to have a centralized place
where to find all the ongoing operations (that led to fix a memory
leak earlier), in the future that could help to debug stalled
operations.
Signed-off-by: Lionel Landwerlin <lionel g landwerlin linux intel com>
---
src/Makefile.am | 5 +-
src/grilo.c | 4 +
src/grilo.h | 1 +
src/grl-media-source.c | 41 +++++-------
src/grl-metadata-source.c | 146 ++++++++++++++++++----------------------
src/grl-metadata-source.h | 13 ++--
src/grl-multiple.c | 86 ++++++++++-------------
src/grl-multiple.h | 2 +-
src/grl-operation-priv.h | 43 ++++++++++++
src/grl-operation.c | 162 ++++++++++++++++++++++++++++++++++++++++++++
src/grl-operation.h | 42 +++++++++++
tools/grilo-test-ui/main.c | 7 +--
12 files changed, 385 insertions(+), 167 deletions(-)
create mode 100644 src/grl-operation-priv.h
create mode 100644 src/grl-operation.c
create mode 100644 src/grl-operation.h
diff --git a/src/Makefile.am b/src/Makefile.am
index 5dd865a..81cf803 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -42,6 +42,7 @@ lib@GRL_NAME@_la_SOURCES = \
grl-plugin-registry.c \
grl-metadata-key.c grl-metadata-key-priv.h \
grl-metadata-source.c grl-metadata-source-priv.h \
+ grl-operation.c grl-operation.h \
grl-type-builtins.c grl-type-builtins.h \
grl-marshal.c grl-marshal.h \
grl-media-source.c grl-util.c \
@@ -76,7 +77,8 @@ lib@GRL_NAME@inc_HEADERS = \
grl-log.h \
grl-multiple.h \
grl-util.h \
- grl-definitions.h
+ grl-definitions.h \
+ grl-operation.h
data_h_headers = \
data/grl-data.h \
@@ -94,6 +96,7 @@ noinst_HEADERS = \
grl-media-plugin-priv.h \
grl-metadata-source-priv.h \
grl-metadata-key-priv.h \
+ grl-operation-priv.h \
grl-sync-priv.h \
grl-type-builtins.h \
grl-marshal.h
diff --git a/src/grilo.c b/src/grilo.c
index 83ad940..8b3f80b 100644
--- a/src/grilo.c
+++ b/src/grilo.c
@@ -35,6 +35,7 @@
#include "grilo.h"
#include "grl-metadata-key-priv.h"
+#include "grl-operation-priv.h"
#include "grl-log-priv.h"
#include "config.h"
@@ -69,6 +70,9 @@ grl_init (gint *argc,
g_type_init ();
+ /* Initialize operations */
+ grl_operation_init ();
+
/* Check options */
ctx = g_option_context_new ("- Grilo initialization");
g_option_context_set_ignore_unknown_options (ctx, TRUE);
diff --git a/src/grilo.h b/src/grilo.h
index 6d4ab71..721031b 100644
--- a/src/grilo.h
+++ b/src/grilo.h
@@ -45,6 +45,7 @@
#include <grl-multiple.h>
#include <grl-util.h>
#include <grl-definitions.h>
+#include <grl-operation.h>
#undef _GRILO_H_INSIDE_
diff --git a/src/grl-media-source.c b/src/grl-media-source.c
index 327020f..5ffe260 100644
--- a/src/grl-media-source.c
+++ b/src/grl-media-source.c
@@ -41,6 +41,8 @@
#include "grl-media-source.h"
#include "grl-metadata-source-priv.h"
+#include "grl-operation.h"
+#include "grl-operation-priv.h"
#include "grl-sync-priv.h"
#include "data/grl-media.h"
#include "data/grl-media-box.h"
@@ -981,8 +983,7 @@ full_resolution_check_waiting_list (GList **waiting_list,
static void
cancel_resolve (gpointer source, gpointer operation_id, gpointer user_data)
{
- grl_metadata_source_cancel (GRL_METADATA_SOURCE (source),
- GPOINTER_TO_UINT (operation_id));
+ grl_operation_cancel (GPOINTER_TO_UINT (operation_id));
}
static void
@@ -1415,8 +1416,7 @@ grl_media_source_browse (GrlMediaSource *source,
relay_chained = TRUE;
}
- browse_id =
- grl_metadata_source_gen_operation_id (GRL_METADATA_SOURCE (source));
+ browse_id = grl_operation_generate_id ();
/* Always hook an own relay callback so we can do some
post-processing before handing out the results
@@ -1618,8 +1618,7 @@ grl_media_source_search (GrlMediaSource *source,
relay_chained = TRUE;
}
- search_id =
- grl_metadata_source_gen_operation_id (GRL_METADATA_SOURCE (source));
+ search_id = grl_operation_generate_id ();
brc = g_new0 (struct BrowseRelayCb, 1);
brc->chained = relay_chained;
@@ -1819,8 +1818,7 @@ grl_media_source_query (GrlMediaSource *source,
relay_chained = TRUE;
}
- query_id =
- grl_metadata_source_gen_operation_id (GRL_METADATA_SOURCE (source));
+ query_id = grl_operation_generate_id ();
brc = g_new0 (struct BrowseRelayCb, 1);
brc->chained = relay_chained;
@@ -1984,8 +1982,7 @@ grl_media_source_metadata (GrlMediaSource *source,
&_keys, FALSE);
}
- metadata_id =
- grl_metadata_source_gen_operation_id (GRL_METADATA_SOURCE (source));
+ metadata_id = grl_operation_generate_id ();
if (flags & GRL_RESOLVE_FULL) {
struct MetadataFullResolutionCtlCb *c;
@@ -2150,7 +2147,7 @@ grl_media_source_supported_operations (GrlMetadataSource *metadata_source)
* taken for that operation after the said callback with error has been called.
*
* Since: 0.1.1
- * Deprecated: 0.1.14: Use grl_metadata_source_cancel() instead
+ * Deprecated: 0.1.14: Use grl_operation_cancel() instead
*/
void
grl_media_source_cancel (GrlMediaSource *source, guint operation_id)
@@ -2160,9 +2157,9 @@ grl_media_source_cancel (GrlMediaSource *source, guint operation_id)
g_return_if_fail (GRL_IS_MEDIA_SOURCE (source));
GRL_WARNING ("grl_media_source_cancel() is deprecated. "
- "Use grl_metadata_source_cancel() instead");
+ "Use grl_operation_cancel() instead");
- grl_metadata_source_cancel (GRL_METADATA_SOURCE (source), operation_id);
+ grl_operation_cancel (operation_id);
}
/**
@@ -2174,7 +2171,7 @@ grl_media_source_cancel (GrlMediaSource *source, guint operation_id)
* Attach a pointer to the specific operation.
*
* Since: 0.1.1
- * Deprecated: 0.1.14: Use grl_metadata_source_set_operation_data() instead
+ * Deprecated: 0.1.14: Use grl_operation_set_data() instead
*/
void
grl_media_source_set_operation_data (GrlMediaSource *source,
@@ -2186,11 +2183,9 @@ grl_media_source_set_operation_data (GrlMediaSource *source,
g_return_if_fail (GRL_IS_MEDIA_SOURCE (source));
GRL_WARNING ("grl_media_source_set_operation_data() is deprecated. "
- "Use instead grl_metadata_source_set_operation_data()");
+ "Use instead grl_operation_set_data()");
- grl_metadata_source_set_operation_data (GRL_METADATA_SOURCE (source),
- operation_id,
- data);
+ grl_operation_set_data (operation_id, data);
}
/**
@@ -2203,7 +2198,7 @@ grl_media_source_set_operation_data (GrlMediaSource *source,
* Returns: (transfer none): The previously attached data.
*
* Since: 0.1.1
- * Deprecated: 0.1.14: Use grl_metadata_source_get_operation_data() instead
+ * Deprecated: 0.1.14: Use grl_operation_get_data() instead
*/
gpointer
grl_media_source_get_operation_data (GrlMediaSource *source,
@@ -2214,10 +2209,9 @@ grl_media_source_get_operation_data (GrlMediaSource *source,
g_return_val_if_fail (GRL_IS_MEDIA_SOURCE (source), NULL);
GRL_WARNING ("grl_metadata_source_get_operation_data() is deprecated. "
- "Use instead grl_metadata_source_get_operation_data()");
+ "Use instead grl_operation_get_data()");
- return grl_metadata_source_get_operation_data (GRL_METADATA_SOURCE (source),
- operation_id);
+ return grl_operation_get_data (operation_id);
}
/**
@@ -2543,8 +2537,7 @@ grl_media_source_get_media_from_uri (GrlMediaSource *source,
&_keys, FALSE);
}
- media_from_uri_id =
- grl_metadata_source_gen_operation_id (GRL_METADATA_SOURCE (source));
+ media_from_uri_id = grl_operation_generate_id ();
/* We cannot prepare for full resolution yet because we don't
have a GrlMedia t operate with.
diff --git a/src/grl-metadata-source.c b/src/grl-metadata-source.c
index 2373460..4cb6690 100644
--- a/src/grl-metadata-source.c
+++ b/src/grl-metadata-source.c
@@ -45,6 +45,8 @@
#include "grl-metadata-source.h"
#include "grl-metadata-source-priv.h"
+#include "grl-operation.h"
+#include "grl-operation-priv.h"
#include "grl-sync-priv.h"
#include "grl-plugin-registry.h"
#include "grl-error.h"
@@ -72,7 +74,6 @@ struct _GrlMetadataSourcePrivate {
gchar *id;
gchar *name;
gchar *desc;
- GHashTable *pending_operations;
};
struct ResolveRelayCb {
@@ -95,9 +96,11 @@ struct SetMetadataCtlCb {
};
struct OperationState {
+ GrlMetadataSource *source;
+ guint operation_id;
+
gboolean cancelled;
gboolean completed;
- gpointer data;
};
static void grl_metadata_source_finalize (GObject *plugin);
@@ -132,8 +135,6 @@ grl_metadata_source_class_init (GrlMetadataSourceClass *metadata_source_class)
metadata_source_class->supported_operations =
grl_metadata_source_supported_operations_impl;
- metadata_source_class->operation_id = 1;
-
/**
* GrlMetadataSource:source-id
*
@@ -185,8 +186,6 @@ static void
grl_metadata_source_init (GrlMetadataSource *source)
{
source->priv = GRL_METADATA_SOURCE_GET_PRIVATE (source);
- source->priv->pending_operations =
- g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
}
static void
@@ -202,8 +201,6 @@ grl_metadata_source_finalize (GObject *object)
g_free (source->priv->name);
g_free (source->priv->desc);
- g_hash_table_unref (source->priv->pending_operations);
-
G_OBJECT_CLASS (grl_metadata_source_parent_class)->finalize (object);
}
@@ -304,7 +301,7 @@ free_set_metadata_ctl_cb_info (struct SetMetadataCtlCb *data)
iter = g_list_next (iter);
}
iter = data->specs;
-
+
g_free (data);
}
@@ -382,6 +379,8 @@ resolve_result_relay_cb (GrlMetadataSource *source,
g_error_free (_error);
}
+ grl_metadata_source_set_operation_finished (source, rrc->spec->resolve_id);
+
g_object_unref (rrc->spec->source);
g_object_unref (rrc->spec->media);
g_list_free (rrc->spec->keys);
@@ -448,7 +447,7 @@ set_metadata_idle (gpointer user_data)
smctlcb = (struct SetMetadataCtlCb *) user_data;
keymap = (struct SourceKeyMap *) smctlcb->next->data;
-
+
sms = g_new0 (GrlMetadataSourceSetMetadataSpec, 1);
sms->source = keymap->source;
sms->keys = keymap->keys;
@@ -794,7 +793,7 @@ grl_metadata_source_key_depends (GrlMetadataSource *source, GrlKeyID key_id)
* @source: a metadata source
*
* Similar to grl_metadata_source_supported_keys(), but these keys
- * are marked as writable, meaning the source allows the client
+ * are marked as writable, meaning the source allows the client
* to provide new values for these keys that will be stored permanently.
*
* Returns: (element-type GObject.ParamSpec) (transfer none):
@@ -951,8 +950,7 @@ grl_metadata_source_resolve (GrlMetadataSource *source,
grl_metadata_source_filter_slow (source, &_keys, FALSE);
}
- resolve_id =
- grl_metadata_source_gen_operation_id (GRL_METADATA_SOURCE (source));
+ resolve_id = grl_operation_generate_id ();
/* Always hook an own relay callback so we can do some
post-processing before handing out the results
@@ -1328,7 +1326,7 @@ grl_metadata_source_get_description (GrlMetadataSource *source)
*
* This is the main method of the #GrlMetadataSource class. It will
* get the values for @keys from @media and store it permanently. After
- * calling this method, future queries that return this media object
+ * calling this method, future queries that return this media object
* shall return this new values for the selected keys.
*
* This function is asynchronous and uses the Glib's main loop.
@@ -1459,6 +1457,7 @@ grl_metadata_source_set_metadata_sync (GrlMetadataSource *source,
* taken for that operation after the said callback with error has been called.
*
* Since: 0.1.14
+ * Deprecated: 0.1.16: Use grl_operation_cancel() instead
*/
void
grl_metadata_source_cancel (GrlMetadataSource *source, guint operation_id)
@@ -1467,27 +1466,7 @@ grl_metadata_source_cancel (GrlMetadataSource *source, guint operation_id)
g_return_if_fail (GRL_IS_METADATA_SOURCE (source));
- if (!grl_metadata_source_operation_is_ongoing (source, operation_id)) {
- GRL_DEBUG ("Tried to cancel invalid or already cancelled operation. "
- "Skipping...");
- return;
- }
-
- /* Mark the operation as finished, if the source does not implement
- cancellation or it did not make it in time, we will not emit the results
- for this operation in any case. At any rate, we will not free the
- operation data until we are sure the plugin won't need it any more. In the
- case of operations dealing with multiple results, like browse() or
- search(), this will happen when it emits remaining = 0 (which can be
- because it did not cancel the op or because it managed to cancel it and is
- signaling so) */
- grl_metadata_source_set_operation_cancelled (source, operation_id);
-
- /* If the source provides an implementation for operation cancellation,
- let's use that to avoid further unnecessary processing in the plugin */
- if (GRL_METADATA_SOURCE_GET_CLASS (source)->cancel) {
- GRL_METADATA_SOURCE_GET_CLASS (source)->cancel (source, operation_id);
- }
+ grl_operation_cancel (operation_id);
}
/**
@@ -1533,25 +1512,18 @@ grl_metadata_source_supported_operations_impl (GrlMetadataSource *source)
* Attach a pointer to the specific operation.
*
* Since: 0.1.14
+ * Deprecated: 0.1.16: Use grl_operation_set_data() instead
*/
void
grl_metadata_source_set_operation_data (GrlMetadataSource *source,
guint operation_id,
gpointer data)
{
- struct OperationState *op_state;
-
GRL_DEBUG ("grl_metadata_source_set_operation_data");
g_return_if_fail (GRL_IS_METADATA_SOURCE (source));
- op_state = g_hash_table_lookup (source->priv->pending_operations,
- GINT_TO_POINTER (operation_id));
- if (op_state) {
- op_state->data = data;
- } else {
- GRL_WARNING ("Tried to set operation data but operation does not exist");
- }
+ grl_operation_set_data (operation_id, data);
}
/**
@@ -1564,35 +1536,17 @@ grl_metadata_source_set_operation_data (GrlMetadataSource *source,
* Returns: (transfer none): The previously attached data.
*
* Since: 0.1.14
+ * Deprecated: 0.1.16: Use grl_operation_get_data() instead
*/
gpointer
grl_metadata_source_get_operation_data (GrlMetadataSource *source,
guint operation_id)
{
- struct OperationState *op_state;
-
GRL_DEBUG ("grl_metadata_source_get_operation_data");
g_return_val_if_fail (GRL_IS_METADATA_SOURCE (source), NULL);
- op_state = g_hash_table_lookup (source->priv->pending_operations,
- GINT_TO_POINTER (operation_id));
- if (op_state) {
- return op_state->data;
- } else {
- GRL_WARNING ("Tried to get operation data but operation does not exist");
- return NULL;
- }
-}
-
-guint
-grl_metadata_source_gen_operation_id (GrlMetadataSource *source)
-{
- GrlMetadataSourceClass *klass;
-
- klass = GRL_METADATA_SOURCE_GET_CLASS (source);
-
- return klass->operation_id++;
+ return grl_operation_get_data (operation_id);
}
/*
@@ -1621,8 +1575,7 @@ grl_metadata_source_set_operation_finished (GrlMetadataSource *source,
{
GRL_DEBUG ("grl_metadata_source_set_operation_finished (%d)", operation_id);
- g_hash_table_remove (source->priv->pending_operations,
- GINT_TO_POINTER (operation_id));
+ grl_operation_remove (operation_id);
}
/*
@@ -1637,8 +1590,8 @@ grl_metadata_source_operation_is_finished (GrlMetadataSource *source,
{
struct OperationState *op_state;
- op_state = g_hash_table_lookup (source->priv->pending_operations,
- GINT_TO_POINTER (operation_id));
+ op_state = grl_operation_get_private_data (operation_id);
+
return op_state == NULL;
}
@@ -1656,8 +1609,7 @@ grl_metadata_source_set_operation_completed (GrlMetadataSource *source,
GRL_DEBUG ("grl_metadata_source_set_operation_completed (%d)", operation_id);
- op_state = g_hash_table_lookup (source->priv->pending_operations,
- GINT_TO_POINTER (operation_id));
+ op_state = grl_operation_get_private_data (operation_id);
if (op_state) {
op_state->completed = TRUE;
@@ -1677,8 +1629,8 @@ grl_metadata_source_operation_is_completed (GrlMetadataSource *source,
{
struct OperationState *op_state;
- op_state = g_hash_table_lookup (source->priv->pending_operations,
- GINT_TO_POINTER (operation_id));
+ op_state = grl_operation_get_private_data (operation_id);
+
return !op_state || op_state->completed;
}
@@ -1696,8 +1648,7 @@ grl_metadata_source_set_operation_cancelled (GrlMetadataSource *source,
GRL_DEBUG ("grl_metadata_source_set_operation_cancelled (%d)", operation_id);
- op_state = g_hash_table_lookup (source->priv->pending_operations,
- GINT_TO_POINTER (operation_id));
+ op_state = grl_operation_get_private_data (operation_id);
if (op_state) {
op_state->cancelled = TRUE;
@@ -1717,11 +1668,42 @@ grl_metadata_source_operation_is_cancelled (GrlMetadataSource *source,
{
struct OperationState *op_state;
- op_state = g_hash_table_lookup (source->priv->pending_operations,
- GINT_TO_POINTER (operation_id));
+ op_state = grl_operation_get_private_data (operation_id);
+
return op_state && op_state->cancelled;
}
+static void
+grl_metadata_source_cancel_cb (struct OperationState *op_state)
+{
+ GrlMetadataSource *source = op_state->source;
+
+ if (!grl_metadata_source_operation_is_ongoing (source,
+ op_state->operation_id)) {
+ GRL_DEBUG ("Tried to cancel invalid or already cancelled operation. "
+ "Skipping...");
+ return;
+ }
+
+ /* Mark the operation as finished, if the source does not implement
+ cancellation or it did not make it in time, we will not emit the results
+ for this operation in any case. At any rate, we will not free the
+ operation data until we are sure the plugin won't need it any more. In the
+ case of operations dealing with multiple results, like browse() or
+ search(), this will happen when it emits remaining = 0 (which can be
+ because it did not cancel the op or because it managed to cancel it and is
+ signaling so) */
+ grl_metadata_source_set_operation_cancelled (source,
+ op_state->operation_id);
+
+ /* If the source provides an implementation for operation cancellation,
+ let's use that to avoid further unnecessary processing in the plugin */
+ if (GRL_METADATA_SOURCE_GET_CLASS (source)->cancel) {
+ GRL_METADATA_SOURCE_GET_CLASS (source)->cancel (source,
+ op_state->operation_id);
+ }
+}
+
/*
* grl_metadata_source_set_operation_ongoing:
*
@@ -1737,8 +1719,12 @@ grl_metadata_source_set_operation_ongoing (GrlMetadataSource *source,
GRL_DEBUG ("set_operation_ongoing (%d)", operation_id);
op_state = g_new0 (struct OperationState, 1);
- g_hash_table_insert (source->priv->pending_operations,
- GINT_TO_POINTER (operation_id), op_state);
+ op_state->source = source;
+ op_state->operation_id = operation_id;
+
+ grl_operation_set_callbacks (operation_id,
+ (GrlOperationCancelCb) grl_metadata_source_cancel_cb,
+ op_state, g_free);
}
/*
@@ -1753,7 +1739,7 @@ grl_metadata_source_operation_is_ongoing (GrlMetadataSource *source,
{
struct OperationState *op_state;
- op_state = g_hash_table_lookup (source->priv->pending_operations,
- GINT_TO_POINTER (operation_id));
+ op_state = grl_operation_get_private_data (operation_id);
+
return op_state && !op_state->cancelled;
}
diff --git a/src/grl-metadata-source.h b/src/grl-metadata-source.h
index 5638813..4238da8 100644
--- a/src/grl-metadata-source.h
+++ b/src/grl-metadata-source.h
@@ -330,12 +330,12 @@ GrlMedia *grl_metadata_source_resolve_sync (GrlMetadataSource *source,
GrlMetadataResolutionFlags flags,
GError **error);
-void grl_metadata_source_set_operation_data (GrlMetadataSource *source,
- guint operation_id,
- gpointer data);
+G_GNUC_DEPRECATED void grl_metadata_source_set_operation_data (GrlMetadataSource *source,
+ guint operation_id,
+ gpointer data);
-gpointer grl_metadata_source_get_operation_data (GrlMetadataSource *source,
- guint operation_id);
+G_GNUC_DEPRECATED gpointer grl_metadata_source_get_operation_data (GrlMetadataSource *source,
+ guint operation_id);
void grl_metadata_source_set_metadata (GrlMetadataSource *source,
GrlMedia *media,
@@ -350,7 +350,8 @@ GList *grl_metadata_source_set_metadata_sync (GrlMetadataSource *source,
GrlMetadataWritingFlags flags,
GError **error);
-void grl_metadata_source_cancel (GrlMetadataSource *source, guint operation_id);
+G_GNUC_DEPRECATED void grl_metadata_source_cancel (GrlMetadataSource *source,
+ guint operation_id);
const gchar *grl_metadata_source_get_id (GrlMetadataSource *source);
diff --git a/src/grl-multiple.c b/src/grl-multiple.c
index c711646..600c90f 100644
--- a/src/grl-multiple.c
+++ b/src/grl-multiple.c
@@ -35,6 +35,8 @@
#include "grl-multiple.h"
#include "grl-sync-priv.h"
+#include "grl-operation.h"
+#include "grl-operation-priv.h"
#include "grl-plugin-registry.h"
#include "grl-error.h"
#include "grl-log.h"
@@ -84,11 +86,10 @@ static void multiple_search_cb (GrlMediaSource *source,
guint remaining,
gpointer user_data,
const GError *error);
+static void multiple_search_cancel_cb (struct MultipleSearchData *msd);
-/* ================= Globals ================= */
-static GHashTable *pending_operations = NULL;
-static gint multiple_search_id = 1;
+/* ================= Globals ================= */
/* ================ Utitilies ================ */
@@ -150,7 +151,7 @@ start_multiple_search_operation (guint search_id,
gpointer user_data)
{
GRL_DEBUG ("start_multiple_search_operation");
-
+
struct MultipleSearchData *msd;
GList *iter_sources, *iter_skips;
guint n, first_count, individual_count;
@@ -195,7 +196,7 @@ start_multiple_search_operation (guint search_id,
rc->count = c;
g_hash_table_insert (msd->table, source, rc);
- /* Check if we have to apply a "skip" parameter to this source
+ /* Check if we have to apply a "skip" parameter to this source
(useful when we are chaining queries to complete the result count) */
if (iter_skips) {
skip = GPOINTER_TO_INT (iter_skips->data);
@@ -228,8 +229,10 @@ start_multiple_search_operation (guint search_id,
}
/* This frees the previous msd structure (if this operation is chained) */
- g_hash_table_insert (pending_operations,
- GINT_TO_POINTER (msd->search_id), msd);
+ grl_operation_set_callbacks (msd->search_id,
+ (GrlOperationCancelCb) multiple_search_cancel_cb,
+ msd,
+ (GDestroyNotify) free_multiple_search_data);
return msd;
}
@@ -361,7 +364,7 @@ multiple_search_cb (GrlMediaSource *source,
rc = (struct ResultCount *)
g_hash_table_lookup (msd->table, (gpointer) source);
-
+
if (media) {
rc->received++;
}
@@ -432,7 +435,8 @@ multiple_search_cb (GrlMediaSource *source,
operation_done:
GRL_DEBUG ("Multiple operation finished (%u)", msd->search_id);
- g_hash_table_remove (pending_operations, GINT_TO_POINTER (msd->search_id));
+
+ grl_operation_remove (msd->search_id);
}
static void
@@ -509,20 +513,13 @@ grl_multiple_search (const GList *sources,
GList *sources_list;
struct MultipleSearchData *msd;
gboolean allocated_sources_list = FALSE;
+ guint operation_id;
GRL_DEBUG ("grl_multiple_search");
g_return_val_if_fail (count > 0, 0);
g_return_val_if_fail (callback != NULL, 0);
- if (!pending_operations) {
- pending_operations =
- g_hash_table_new_full (g_direct_hash,
- g_direct_equal,
- NULL,
- (GDestroyNotify) free_multiple_search_data);
- }
-
/* If no sources have been provided then get the list of all
searchable sources from the registry */
if (!sources) {
@@ -543,8 +540,8 @@ grl_multiple_search (const GList *sources,
}
/* Start multiple search operation */
- multiple_search_id++;
- msd = start_multiple_search_operation (multiple_search_id,
+ operation_id = grl_operation_generate_id ();
+ msd = start_multiple_search_operation (operation_id,
sources,
text,
keys,
@@ -560,37 +557,11 @@ grl_multiple_search (const GList *sources,
return msd->search_id;
}
-/**
- * grl_multiple_cancel:
- * @search_id: the identifier of the multiple operation to cancel
- *
- * Cancel a running multiple search by issuing a cancel operation on each
- * source involved involved in the operation.
- *
- * Since: 0.1.6
- */
-void
-grl_multiple_cancel (guint search_id)
+static void
+multiple_search_cancel_cb (struct MultipleSearchData *msd)
{
- GRL_DEBUG ("grl_multiple_cancel");
-
- struct MultipleSearchData *msd;
GList *sources, *ids;
- if (!pending_operations) {
- GRL_DEBUG ("No pending operations. Skipping...");
- return;
- }
-
- /* Retrieve the tracking data for operation 'search_id' */
- msd = (struct MultipleSearchData *)
- g_hash_table_lookup (pending_operations, GINT_TO_POINTER (search_id));
- if (!msd) {
- GRL_DEBUG ("Tried to cancel invalid or already cancelled multiple "
- "operation. Skipping...");
- return;
- }
-
/* Go through all the sources involved in that operation and issue
cancel() operations for each one */
sources = msd->sources;
@@ -599,8 +570,7 @@ grl_multiple_cancel (guint search_id)
GRL_DEBUG ("cancelling operation %s:%u",
grl_metadata_source_get_name (GRL_METADATA_SOURCE (sources->data)),
GPOINTER_TO_UINT (ids->data));
- grl_metadata_source_cancel (GRL_METADATA_SOURCE (sources->data),
- GPOINTER_TO_INT (ids->data));
+ grl_operation_cancel (GPOINTER_TO_INT (ids->data));
sources = g_list_next (sources);
ids = g_list_next (ids);
}
@@ -612,6 +582,24 @@ grl_multiple_cancel (guint search_id)
}
/**
+ * grl_multiple_cancel:
+ * @search_id: the identifier of the multiple operation to cancel
+ *
+ * Cancel a running multiple search by issuing a cancel operation on each
+ * source involved involved in the operation.
+ *
+ * Since: 0.1.6
+ * Deprecated: 0.1.16: Use grl_operation_cancel() instead
+ */
+void
+grl_multiple_cancel (guint search_id)
+{
+ GRL_DEBUG ("grl_multiple_cancel");
+
+ grl_operation_cancel (search_id);
+}
+
+/**
* grl_multiple_search_sync:
* @sources: (element-type Grl.MediaSource) (allow-none):
* a #GList of #GrlMediaSource<!-- -->s where to search from (%NULL for all
diff --git a/src/grl-multiple.h b/src/grl-multiple.h
index 035c120..b968b08 100644
--- a/src/grl-multiple.h
+++ b/src/grl-multiple.h
@@ -46,7 +46,7 @@ GList *grl_multiple_search_sync (const GList *sources,
GrlMetadataResolutionFlags flags,
GError **error);
-void grl_multiple_cancel (guint search_id);
+G_GNUC_DEPRECATED void grl_multiple_cancel (guint search_id);
void grl_multiple_get_media_from_uri (const gchar *uri,
const GList *keys,
diff --git a/src/grl-operation-priv.h b/src/grl-operation-priv.h
new file mode 100644
index 0000000..e4dc01f
--- /dev/null
+++ b/src/grl-operation-priv.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ *
+ * Contact: Iago Toral Quiroga <itoral igalia com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef _GRL_OPERATION_PRIV_H_
+#define _GRL_OPERATION_PRIV_H_
+
+#include <glib.h>
+
+typedef void (*GrlOperationCancelCb) (gpointer data);
+
+void grl_operation_init (void);
+
+guint grl_operation_generate_id (void);
+
+void grl_operation_set_callbacks (guint operation_id,
+ GrlOperationCancelCb cancel_cb,
+ gpointer private_data,
+ GDestroyNotify destroy_cb);
+
+gpointer grl_operation_get_private_data (guint operation_id);
+
+void grl_operation_remove (guint operation_id);
+
+#endif /* _GRL_OPERATION_PRIV_H_ */
diff --git a/src/grl-operation.c b/src/grl-operation.c
new file mode 100644
index 0000000..5e6a231
--- /dev/null
+++ b/src/grl-operation.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ *
+ * Contact: Iago Toral Quiroga <itoral igalia com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include "grl-operation.h"
+#include "grl-operation-priv.h"
+
+typedef struct
+{
+ GrlOperationCancelCb cancel_cb;
+ GDestroyNotify destroy_cb;
+ gpointer private_data;
+ gpointer user_data;
+} OperationData;
+
+static guint operations_id;
+static GHashTable *operations;
+
+static void
+operation_data_free (gpointer data)
+{
+ g_slice_free (OperationData, data);
+}
+
+void
+grl_operation_init (void)
+{
+ static gboolean initialized = FALSE;
+
+ if (G_LIKELY (initialized))
+ return;
+
+ initialized = TRUE;
+ operations = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+ NULL, operation_data_free);
+ operations_id = 1;
+}
+
+guint
+grl_operation_generate_id (void)
+{
+ guint operation_id = operations_id++;
+ OperationData *data = g_slice_new0 (OperationData);
+
+ g_hash_table_insert (operations, GUINT_TO_POINTER (operation_id), data);
+
+ return operation_id;
+}
+
+void
+grl_operation_set_callbacks (guint operation_id,
+ GrlOperationCancelCb cancel_cb,
+ gpointer private_data,
+ GDestroyNotify destroy_cb)
+{
+ OperationData *data = g_hash_table_lookup (operations,
+ GUINT_TO_POINTER (operation_id));
+
+ g_return_if_fail (data != NULL);
+
+ data->cancel_cb = cancel_cb;
+ data->destroy_cb = destroy_cb;
+ data->private_data = private_data;
+}
+
+gpointer
+grl_operation_get_private_data (guint operation_id)
+{
+ OperationData *data = g_hash_table_lookup (operations,
+ GUINT_TO_POINTER (operation_id));
+
+ g_return_val_if_fail (data != NULL, NULL);
+
+ return data->private_data;
+}
+
+void
+grl_operation_remove (guint operation_id)
+{
+ g_hash_table_remove (operations, GUINT_TO_POINTER (operation_id));
+}
+
+/**/
+
+/**
+ * grl_operation_cancel:
+ * @operation_id: the identifier of a running operation
+ *
+ * Cancel an operation.
+ *
+ * Since: 0.1.16
+ */
+void
+grl_operation_cancel (guint operation_id)
+{
+ OperationData *data = g_hash_table_lookup (operations,
+ GUINT_TO_POINTER (operation_id));
+
+ g_return_if_fail (data != NULL);
+
+ data->cancel_cb (data->private_data);
+}
+
+/**
+ * grl_operation_get_data:
+ * @operation_id: the identifier of a running operation
+ *
+ * Obtains the previously attached data
+ *
+ * Returns: (transfer none): The previously attached data.
+ *
+ * Since: 0.1.16
+ */
+gpointer
+grl_operation_get_data (guint operation_id)
+{
+ OperationData *data = g_hash_table_lookup (operations,
+ GUINT_TO_POINTER (operation_id));
+
+ g_return_val_if_fail (data != NULL, NULL);
+
+ return data->user_data;
+}
+
+/**
+ * grl_operation_set_data:
+ * @operation_id: the identifier of a running operation
+ * @data: the data to attach
+ *
+ * Attach a pointer to the specific operation.
+ *
+ * Since: 0.1.16
+ */
+void
+grl_operation_set_data (guint operation_id, gpointer user_data)
+{
+ OperationData *data = g_hash_table_lookup (operations,
+ GUINT_TO_POINTER (operation_id));
+
+ g_return_if_fail (data != NULL);
+
+ data->user_data = user_data;
+}
+
diff --git a/src/grl-operation.h b/src/grl-operation.h
new file mode 100644
index 0000000..c96356c
--- /dev/null
+++ b/src/grl-operation.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2011 Igalia S.L.
+ *
+ * Contact: Iago Toral Quiroga <itoral igalia com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#if !defined (_GRILO_H_INSIDE_) && !defined (GRILO_COMPILATION)
+#error "Only <grilo.h> can be included directly."
+#endif
+
+#ifndef _GRL_OPERATION_H_
+#define _GRL_OPERATION_H_
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+void grl_operation_cancel (guint operation_id);
+
+gpointer grl_operation_get_data (guint operation_id);
+
+void grl_operation_set_data (guint operation_id, gpointer user_data);
+
+G_END_DECLS
+
+#endif /* _GRL_OPERATION_H_ */
diff --git a/tools/grilo-test-ui/main.c b/tools/grilo-test-ui/main.c
index 37ac2fd..b21a0d7 100644
--- a/tools/grilo-test-ui/main.c
+++ b/tools/grilo-test-ui/main.c
@@ -506,12 +506,7 @@ static void
cancel_current_operation (void)
{
if (ui_state->op_ongoing) {
- if (!ui_state->multiple) {
- grl_metadata_source_cancel (GRL_METADATA_SOURCE (ui_state->cur_op_source),
- ui_state->cur_op_id);
- } else {
- grl_multiple_cancel (ui_state->cur_op_id);
- }
+ grl_operation_cancel (ui_state->cur_op_id);
ui_state->op_ongoing = FALSE;
}
}
--
1.7.5.4
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]