Re: [PATCH] core: introduce grilo operations



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]