[gom] gom: Don't do get/set properties in != main thread when saving
- From: Bastien Nocera <hadess src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gom] gom: Don't do get/set properties in != main thread when saving
- Date: Tue, 4 Nov 2014 18:56:29 +0000 (UTC)
commit b14e7044bf5cbfe4b6baac4b3ce66dba7dc8f458
Author: Bastien Nocera <hadess hadess net>
Date: Tue Nov 4 13:33:17 2014 +0100
gom: Don't do get/set properties in != main thread when saving
Avoid manipulating properties from within a thread other than the
main thread when saving. This breaks Javascript and Python bindings.
Note, reading from the database is likely still broken though.
https://bugzilla.gnome.org/show_bug.cgi?id=728301
gom/gom-resource.c | 120 +++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 96 insertions(+), 24 deletions(-)
---
diff --git a/gom/gom-resource.c b/gom/gom-resource.c
index 21e4456..4680918 100644
--- a/gom/gom-resource.c
+++ b/gom/gom-resource.c
@@ -544,22 +544,48 @@ has_primary_key (GomResource *resource)
return ret;
}
-static gboolean
-gom_resource_do_save (GomResource *resource,
- GomAdapter *adapter,
- GError **error)
+static void
+set_post_save_properties (GomResource *resource)
+{
+ GValue *value;
+
+ gom_resource_set_is_from_table(resource,
+ GPOINTER_TO_INT(g_object_get_data(G_OBJECT(resource), "is-from-table")));
+ g_object_set_data (G_OBJECT(resource), "is-from-table", NULL);
+
+ value = g_object_get_data(G_OBJECT(resource), "row-id");
+ if (!value)
+ return;
+ set_pkey(resource, value);
+ g_object_set_data(G_OBJECT(resource), "row-id", NULL);
+}
+
+static void
+free_save_cmds (gpointer data)
+{
+ GList *cmds = data;
+
+ g_list_free_full (cmds, g_object_unref);
+}
+
+static void
+value_free (gpointer data)
+{
+ GValue *value = data;
+ g_value_unset (value);
+ g_free (value);
+}
+
+static void
+gom_resource_build_save_cmd (GomResource *resource,
+ GomAdapter *adapter)
{
GomCommandBuilder *builder;
- gboolean ret = FALSE;
- gboolean is_insert;
- gint64 row_id = -1;
+ gboolean has_pkey, is_insert;
GSList *types = NULL;
GSList *iter;
GType resource_type;
- gboolean has_pkey;
-
- g_return_val_if_fail(GOM_IS_RESOURCE(resource), FALSE);
- g_return_val_if_fail(GOM_IS_ADAPTER(adapter), FALSE);
+ GList *cmds = NULL;
resource_type = G_TYPE_FROM_INSTANCE(resource);
g_assert(g_type_is_a(resource_type, GOM_TYPE_RESOURCE));
@@ -577,6 +603,8 @@ gom_resource_do_save (GomResource *resource,
is_insert = TRUE;
}
+ g_object_set_data (G_OBJECT (resource), "is-insert", GINT_TO_POINTER (is_insert));
+
do {
types = g_slist_prepend(types, GINT_TO_POINTER(resource_type));
} while ((resource_type = g_type_parent(resource_type)) != GOM_TYPE_RESOURCE);
@@ -596,33 +624,66 @@ gom_resource_do_save (GomResource *resource,
command = gom_command_builder_build_update(builder, resource);
}
- if (!gom_command_execute(command, NULL, error)) {
- g_object_unref(command);
+ if (is_insert && gom_resource_has_dynamic_pkey(resource_type))
+ is_insert = FALSE;
+
+ cmds = g_list_prepend (cmds, command);
+ }
+
+ cmds = g_list_reverse (cmds);
+ g_object_set_data_full (G_OBJECT(resource), "save-commands", cmds, free_save_cmds);
+
+ g_slist_free(types);
+ g_object_unref (builder);
+}
+
+static gboolean
+gom_resource_do_save (GomResource *resource,
+ GomAdapter *adapter,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ gboolean is_insert;
+ gint64 row_id = -1;
+ GType resource_type;
+ GList *cmds, *l;
+
+ g_return_val_if_fail(GOM_IS_RESOURCE(resource), FALSE);
+ g_return_val_if_fail(GOM_IS_ADAPTER(adapter), FALSE);
+
+ resource_type = G_TYPE_FROM_INSTANCE(resource);
+ g_assert(g_type_is_a(resource_type, GOM_TYPE_RESOURCE));
+
+ is_insert = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(resource), "is-insert"));
+ cmds = g_object_get_data(G_OBJECT(resource), "save-commands");
+
+ for (l = cmds; l != NULL; l = l->next) {
+ GomCommand *command = l->data;
+
+ if (!gom_command_execute(command, NULL, error))
goto out;
- }
if (is_insert && row_id == -1 && gom_resource_has_dynamic_pkey(resource_type)) {
sqlite3 *handle = gom_adapter_get_handle(adapter);
- GValue value = { 0 };
+ GValue *value;
row_id = sqlite3_last_insert_rowid(handle);
- g_value_init(&value, G_TYPE_INT64);
- g_value_set_int64(&value, row_id);
- set_pkey(resource, &value);
- gom_resource_set_is_from_table(resource, TRUE);
- g_value_unset(&value);
+ value = g_new0 (GValue, 1);
+ g_value_init(value, G_TYPE_INT64);
+ g_value_set_int64(value, row_id);
+ g_object_set_data_full(G_OBJECT(resource), "row-id", value, value_free);
+
+ g_object_set_data (G_OBJECT(resource), "is-from-table", GINT_TO_POINTER(TRUE));
is_insert = FALSE;
}
-
- g_object_unref(command);
}
ret = TRUE;
out:
- g_slist_free(types);
- g_object_unref(builder);
+ g_object_set_data (G_OBJECT (resource), "save-commands", NULL);
+ g_object_set_data (G_OBJECT (resource), "is-insert", NULL);
return ret;
}
@@ -692,6 +753,8 @@ gom_resource_save_sync (GomResource *resource,
g_object_set_data(G_OBJECT(simple), "queue", queue);
g_assert(GOM_IS_ADAPTER(adapter));
+ gom_resource_build_save_cmd(resource, adapter);
+
gom_adapter_queue_write(adapter, gom_resource_save_cb, simple);
g_async_queue_pop(queue);
g_async_queue_unref(queue);
@@ -699,6 +762,10 @@ gom_resource_save_sync (GomResource *resource,
if (!(ret = g_simple_async_result_get_op_res_gboolean(simple))) {
g_simple_async_result_propagate_error(simple, error);
}
+
+ if (ret)
+ set_post_save_properties(resource);
+
g_object_unref(simple);
return ret;
@@ -727,6 +794,7 @@ gom_resource_save_async (GomResource *resource,
gom_resource_save_async);
adapter = gom_repository_get_adapter(priv->repository);
g_assert(GOM_IS_ADAPTER(adapter));
+ gom_resource_build_save_cmd(resource, adapter);
gom_adapter_queue_write(adapter, gom_resource_save_cb, simple);
}
@@ -744,6 +812,10 @@ gom_resource_save_finish (GomResource *resource,
if (!(ret = g_simple_async_result_get_op_res_gboolean(simple))) {
g_simple_async_result_propagate_error(simple, error);
}
+
+ if (ret)
+ set_post_save_properties(resource);
+
g_object_unref(simple);
return ret;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]