Re: [PATCH] core: introduce grilo operations
- From: Iago Toral Quiroga <itoral igalia com>
- To: grilo-list gnome org
- Subject: Re: [PATCH] core: introduce grilo operations
- Date: Fri, 17 Jun 2011 10:39:40 +0200
Hi Lionel,
You are right, this makes a lot of sense and will make things easier.
Thanks for the patch!
Juan or Guillaume, could you have a look at it?
Iago
El jue, 16-06-2011 a las 19:15 +0100,
lionel g landwerlin linux intel com escribió:
> 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;
> }
> }
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]