[grilo-plugins] lua-factory: support to cancel operation
- From: Victor Toso de Carvalho <victortoso src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [grilo-plugins] lua-factory: support to cancel operation
- Date: Mon, 6 Jun 2016 09:05:49 +0000 (UTC)
commit 173958f16f9455694921cc2382e47328bf59ca85
Author: Victor Toso <me victortoso com>
Date: Tue Mar 29 23:11:34 2016 +0200
lua-factory: support to cancel operation
Grilo has optional method to cancel operations which Lua-Factory had
not implemented so far, till now.
For each operation we create a GCancellabe that should be used in
async functions in Lua-Library such as grl.fetch and grl.unzip.
The grl_lua_operations_cancel_operation(), will cancel the operation,
remove the OperationSpec from its internals and free the related data.
https://bugzilla.gnome.org/show_bug.cgi?id=764077
src/lua-factory/grl-lua-common.h | 2 +
src/lua-factory/grl-lua-factory.c | 20 ++++++++++++++
src/lua-factory/grl-lua-library-operations.c | 35 +++++++++++++++++++++++++
src/lua-factory/grl-lua-library.c | 36 ++++++++++++++++++--------
4 files changed, 82 insertions(+), 11 deletions(-)
---
diff --git a/src/lua-factory/grl-lua-common.h b/src/lua-factory/grl-lua-common.h
index b27d480..92ef36e 100644
--- a/src/lua-factory/grl-lua-common.h
+++ b/src/lua-factory/grl-lua-common.h
@@ -76,6 +76,7 @@ typedef struct _OperationSpec {
GrlSource *source;
guint operation_id;
GrlOperationOptions *options;
+ GCancellable *cancellable;
GList *keys;
LuaOperationType op_type;
union {
@@ -95,6 +96,7 @@ void grl_lua_library_save_goa_data (lua_State *L, gpointer goa_object);
void grl_lua_operations_init_priv_state (lua_State *L);
void grl_lua_operations_set_proxy_table (lua_State *L, gint index);
void grl_lua_operations_set_source_state (lua_State *L, LuaSourceState state, OperationSpec *os);
+void grl_lua_operations_cancel_operation (lua_State *L, guint operation_id);
OperationSpec * grl_lua_operations_get_current_op (lua_State *L);
gboolean grl_lua_operations_pcall (lua_State *L, gint nargs, OperationSpec *os, GError **err);
diff --git a/src/lua-factory/grl-lua-factory.c b/src/lua-factory/grl-lua-factory.c
index a11dfee..3f14427 100644
--- a/src/lua-factory/grl-lua-factory.c
+++ b/src/lua-factory/grl-lua-factory.c
@@ -134,6 +134,9 @@ static const GList *grl_lua_factory_source_supported_keys (GrlSource *source);
static const GList *grl_lua_factory_source_slow_keys(GrlSource *source);
+static void grl_lua_factory_source_cancel (GrlSource *source,
+ guint operation_id);
+
static void grl_lua_factory_source_search (GrlSource *source,
GrlSourceSearchSpec *ss);
@@ -511,6 +514,7 @@ grl_lua_factory_source_class_init (GrlLuaFactorySourceClass *klass)
source_class->query = grl_lua_factory_source_query;
source_class->resolve = grl_lua_factory_source_resolve;
source_class->may_resolve = grl_lua_factory_source_may_resolve;
+ source_class->cancel = grl_lua_factory_source_cancel;
g_type_class_add_private (klass, sizeof (GrlLuaFactorySourcePrivate));
}
@@ -1510,6 +1514,18 @@ grl_lua_factory_source_supported_operations (GrlSource *source)
}
static void
+grl_lua_factory_source_cancel (GrlSource *source,
+ guint operation_id)
+{
+ GrlLuaFactorySource *lua_source = GRL_LUA_FACTORY_SOURCE (source);
+ lua_State *L = lua_source->priv->l_st;
+
+ GRL_DEBUG ("grl_lua_factory_source_cancel (%s) %u",
+ grl_source_get_id (source), operation_id);
+ grl_lua_operations_cancel_operation (L, operation_id);
+}
+
+static void
grl_lua_factory_source_search (GrlSource *source,
GrlSourceSearchSpec *ss)
{
@@ -1526,6 +1542,7 @@ grl_lua_factory_source_search (GrlSource *source,
os = g_slice_new0 (OperationSpec);
os->source = ss->source;
os->operation_id = ss->operation_id;
+ os->cancellable = g_cancellable_new ();
os->cb.result = ss->callback;
os->user_data = ss->user_data;
os->string = g_strdup (text);
@@ -1562,6 +1579,7 @@ grl_lua_factory_source_browse (GrlSource *source,
os = g_slice_new0 (OperationSpec);
os->source = bs->source;
os->operation_id = bs->operation_id;
+ os->cancellable = g_cancellable_new ();
os->media = bs->container;
os->cb.result = bs->callback;
os->user_data = bs->user_data;
@@ -1599,6 +1617,7 @@ grl_lua_factory_source_query (GrlSource *source,
os = g_slice_new0 (OperationSpec);
os->source = qs->source;
os->operation_id = qs->operation_id;
+ os->cancellable = g_cancellable_new ();
os->cb.result = qs->callback;
os->user_data = qs->user_data;
os->string = g_strdup (query);
@@ -1632,6 +1651,7 @@ grl_lua_factory_source_resolve (GrlSource *source,
os = g_slice_new0 (OperationSpec);
os->source = rs->source;
os->operation_id = rs->operation_id;
+ os->cancellable = g_cancellable_new ();
os->cb.resolve = rs->callback;
os->media = rs->media;
os->user_data = rs->user_data;
diff --git a/src/lua-factory/grl-lua-library-operations.c b/src/lua-factory/grl-lua-library-operations.c
index 68ec319..a58398b 100644
--- a/src/lua-factory/grl-lua-library-operations.c
+++ b/src/lua-factory/grl-lua-library-operations.c
@@ -47,6 +47,11 @@ free_operation_spec (OperationSpec *os)
g_clear_pointer (&os->string, g_free);
g_clear_object (&os->options);
+ if (os->cancellable) {
+ g_cancellable_cancel (os->cancellable);
+ g_clear_object (&os->cancellable);
+ }
+
if (os->keys)
g_list_free (os->keys);
@@ -674,6 +679,36 @@ grl_lua_operations_get_current_op (lua_State *L)
return os;
}
+void
+grl_lua_operations_cancel_operation (lua_State *L,
+ guint operation_id)
+{
+ OperationSpec *os, *current_os;
+ LuaSourceState state;
+
+ os = priv_state_operations_source_get_op_data (L, operation_id);
+ g_return_if_fail (os != NULL);
+
+ state = priv_state_operations_source_get_state (L, operation_id);
+ if (state != LUA_SOURCE_WAITING) {
+ GRL_DEBUG ("Can't cancel operation (%u) on source (%s) with as state is: %s",
+ operation_id, grl_source_get_id (os->source),
+ source_op_state_str[state]);
+ return;
+ }
+
+ /* All async operations on lua-library should verify os->cancellable to
+ * proper handling the cancelation of ongoing operation */
+ g_cancellable_cancel (os->cancellable);
+
+ current_os = priv_state_current_op_get_op_data (L);
+
+ priv_state_operations_remove_source_state (L, os->operation_id);
+ if (current_os != NULL && current_os->operation_id == os->operation_id)
+ priv_state_current_op_remove (L);
+ free_operation_spec (os);
+}
+
/*
* This is a wrapper to do execute the lua_pcall and all internals that might
* be necessary to Lua-Library before calling the Lua function. The stack
diff --git a/src/lua-factory/grl-lua-library.c b/src/lua-factory/grl-lua-library.c
index c70be08..7711bbc 100644
--- a/src/lua-factory/grl-lua-library.c
+++ b/src/lua-factory/grl-lua-library.c
@@ -53,6 +53,7 @@ typedef struct {
guint num_urls;
gboolean is_table;
gchar **results;
+ GCancellable *cancellable;
OperationSpec *os;
} FetchOperation;
@@ -62,6 +63,7 @@ typedef struct {
gint lua_callback;
gchar *url;
gchar **filenames;
+ GCancellable *cancellable;
OperationSpec *os;
} UnzipOperation;
@@ -479,6 +481,10 @@ grl_util_fetch_done (GObject *source_object,
if (!grl_net_wc_request_finish (GRL_NET_WC (source_object),
res, &data, &len, &err)) {
+ if (g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ GRL_DEBUG ("fetch operation was cancelled");
+ goto free_fetch_op;
+ }
data = NULL;
} else if (!g_utf8_validate(data, len, NULL)) {
fixed = g_convert (data, len, "UTF-8", "ISO8859-1", NULL, NULL, NULL);
@@ -536,6 +542,8 @@ grl_util_fetch_done (GObject *source_object,
}
}
+free_fetch_op:
+ g_object_unref (fo->cancellable);
luaL_unref (L, LUA_REGISTRYINDEX, fo->lua_userdata);
luaL_unref (L, LUA_REGISTRYINDEX, fo->lua_callback);
@@ -638,13 +646,16 @@ grl_util_unzip_done (GObject *source_object,
OperationSpec *os = uo->os;
char **results;
- grl_net_wc_request_finish (GRL_NET_WC (source_object),
- res, &data, &len, &err);
-
- if (err != NULL) {
+ if (!grl_net_wc_request_finish (GRL_NET_WC (source_object),
+ res, &data, &len, &err)) {
guint len, i;
- GRL_WARNING ("Can't fetch zip file (URL: %s): '%s'", uo->url, err->message);
- g_error_free (err);
+ if (g_error_matches (err, GRL_NET_WC_ERROR, GRL_NET_WC_ERROR_CANCELLED)) {
+ GRL_DEBUG ("unzip operation was cancelled");
+ goto free_unzip_op;
+ } else if (err != NULL) {
+ GRL_WARNING ("Can't fetch zip file (URL: %s): '%s'", uo->url, err->message);
+ g_error_free (err);
+ }
len = g_strv_length (uo->filenames);
results = g_new0 (gchar *, len + 1);
for (i = 0; i < len; i++)
@@ -674,11 +685,12 @@ grl_util_unzip_done (GObject *source_object,
}
}
- luaL_unref (L, LUA_REGISTRYINDEX, uo->lua_userdata);
- luaL_unref (L, LUA_REGISTRYINDEX, uo->lua_callback);
-
g_strfreev (results);
+free_unzip_op:
+ g_object_unref (uo->cancellable);
+ luaL_unref (L, LUA_REGISTRYINDEX, uo->lua_userdata);
+ luaL_unref (L, LUA_REGISTRYINDEX, uo->lua_callback);
g_strfreev (uo->filenames);
g_free (uo->url);
g_free (uo);
@@ -1204,6 +1216,7 @@ grl_l_fetch (lua_State *L)
fo = g_new0 (FetchOperation, 1);
fo->L = L;
fo->os = os;
+ fo->cancellable = g_object_ref (os->cancellable);
fo->lua_userdata = lua_userdata;
fo->lua_callback = lua_callback;
fo->index = i;
@@ -1212,7 +1225,7 @@ grl_l_fetch (lua_State *L)
fo->is_table = is_table;
fo->results = results;
- grl_net_wc_request_async (wc, urls[i], NULL, grl_util_fetch_done, fo);
+ grl_net_wc_request_async (wc, urls[i], os->cancellable, grl_util_fetch_done, fo);
}
g_object_unref (wc);
g_free (urls);
@@ -1481,13 +1494,14 @@ grl_l_unzip (lua_State *L)
uo = g_new0 (UnzipOperation, 1);
uo->L = L;
+ uo->cancellable = g_object_ref (os->cancellable);
uo->lua_userdata = lua_userdata;
uo->lua_callback = lua_callback;
uo->url = g_strdup (url);
uo->filenames = filenames;
uo->os = os;
- grl_net_wc_request_async (wc, url, NULL, grl_util_unzip_done, uo);
+ grl_net_wc_request_async (wc, url, os->cancellable, grl_util_unzip_done, uo);
g_object_unref (wc);
grl_lua_operations_set_source_state (L, LUA_SOURCE_WAITING, os);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]