From f10cc6a01b9e28fc977696d71dadb7e5e16e45dd Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Thu, 27 Jun 2019 16:04:29 +0200 Subject: [PATCH] gkdbus: async StartServiceByName handled by GTask Change-Id: I65b29cc58c9a275dca3018309c06d25eaf6d6166 --- gio/gkdbus.c | 178 ++++++++++++++++++++++++++++------------------------------- 1 file changed, 83 insertions(+), 95 deletions(-) diff --git a/gio/gkdbus.c b/gio/gkdbus.c index cbc366a..4554025 100755 --- a/gio/gkdbus.c +++ b/gio/gkdbus.c @@ -1656,66 +1656,93 @@ deliver_synthetic_reply (gpointer user_data) return FALSE; } -static gboolean -_g_kdbus_StartServiceByName_helper (gpointer user_data) +static void +send_synthetic_message (GKDBusWorker *worker, + GDBusMessage *message) +{ + SyntheticReplyData *reply_data; + reply_data = g_new0 (SyntheticReplyData, 1); + reply_data->worker = worker; + reply_data->message = message; + g_main_context_invoke (worker->context, deliver_synthetic_reply, reply_data); +} + +static GBusStartServiceReplyFlags +_g_kdbus_send_Ping (GKDBusWorker *worker, + const gchar *name, + GError **error) { - SyntheticReplyData *data; - GKDBusWorker *worker; - GDBusMessage *message; - const gchar *name; GDBusMessage *ping_message; GDBusMessage *reply; - GError *local_error; gboolean ret; - GVariant *body; - - data = (SyntheticReplyData *)user_data; - worker = data->worker; - message = data->message; - - name = NULL; - reply = NULL; - local_error = NULL; - - body = g_dbus_message_get_body (message); - g_variant_get(body, "(su)", &name, NULL); ping_message = g_dbus_message_new_method_call (name, "/", "org.freedesktop.DBus.Peer", "Ping"); - g_dbus_message_set_serial (ping_message, -1); - /* check synchronous */ ret = _g_kdbus_send (worker, ping_message, &reply, 25000, NULL, NULL); + g_object_unref (ping_message); + g_object_unref (reply); + if (!ret) { - gchar *dbus_error_name; + g_set_error (error, + G_DBUS_ERROR, + G_DBUS_ERROR_SERVICE_UNKNOWN, + "The name %s was not provided by any .service files", name); + return G_BUS_START_SERVICE_REPLY_ERROR; + } + return G_BUS_START_SERVICE_REPLY_SUCCESS; +} - g_set_error (&local_error, - G_DBUS_ERROR, - G_DBUS_ERROR_SERVICE_UNKNOWN, - "The name %s was not provided by any .service files", g_dbus_message_get_destination(message)); +static void +_g_kdbus_send_Ping_thread (GTask *task, + gpointer source_object, + gpointer task_data, + GCancellable *cancellable) +{ + GKDBusWorker *worker = source_object; + GDBusMessage *message = task_data; + const gchar *name = NULL; + GError *error = NULL; - dbus_error_name = g_dbus_error_encode_gerror (local_error); - reply = g_dbus_message_new_method_error (message, dbus_error_name, "%s", local_error->message); + GBusStartServiceReplyFlags status; - g_free (dbus_error_name); - g_error_free (local_error); + g_variant_get (g_dbus_message_get_body (message), "(su)", &name, NULL); + + status = _g_kdbus_send_Ping (worker, name, &error); + g_free ((gchar*) name); + + if (status == G_BUS_START_SERVICE_REPLY_SUCCESS) + g_task_return_int (task, G_BUS_START_SERVICE_REPLY_SUCCESS); + else + g_task_return_error (task, error); + +} + +static void +_g_kdbus_send_Ping_finish (GKDBusWorker *worker, + GAsyncResult *result, + gpointer user_data) +{ + GDBusMessage *message = user_data; + GDBusMessage *synthetic_reply = NULL; + GError *error = NULL; + gssize status = g_task_propagate_int (G_TASK (result), &error); + if (status != -1) + { + synthetic_reply = g_dbus_message_new_method_reply (message); + g_dbus_message_set_body (synthetic_reply, g_variant_new ("(u)", status)); } else { - reply = g_dbus_message_new_method_reply (message); - g_dbus_message_set_body (reply, g_variant_new ("(u)", G_BUS_START_SERVICE_REPLY_SUCCESS)); + gchar *dbus_error_name = g_dbus_error_encode_gerror (error); + synthetic_reply = g_dbus_message_new_method_error (message, dbus_error_name, "%s", error->message); + g_free (dbus_error_name); + g_error_free (error); } - - g_dbus_message_set_serial (reply, -1); - data->message = reply; - g_main_context_invoke (worker->context, deliver_synthetic_reply, data); - - g_free (name); - g_object_unref (ping_message); g_object_unref (message); - - return FALSE; + g_dbus_message_set_serial (synthetic_reply, -1); + send_synthetic_message (worker, synthetic_reply); } /* < internal > @@ -1735,8 +1762,6 @@ _g_kdbus_StartServiceByName (GKDBusWorker *worker, GDBusMessage *message, GError **error) { - GBusStartServiceReplyFlags status; - if (!g_dbus_is_name (name)) { g_set_error (error, @@ -1751,51 +1776,27 @@ _g_kdbus_StartServiceByName (GKDBusWorker *worker, if (!g_kdbus_NameHasOwner_internal (worker, name)) { - gboolean ret; - GDBusMessage *reply; - gboolean sync; - - reply = NULL; - status = G_BUS_START_SERVICE_REPLY_SUCCESS; - sync = message ? FALSE : TRUE; - - if (sync) + if (!message) { - GDBusMessage *ping_message; - - ping_message = g_dbus_message_new_method_call (name, "/", "org.freedesktop.DBus.Peer", "Ping"); - g_dbus_message_set_serial (ping_message, -1); - - ret = _g_kdbus_send (worker, ping_message, &reply, 25000, NULL, NULL); - g_object_unref (reply); - - if (!ret) - { - status = G_BUS_START_SERVICE_REPLY_ERROR; - - g_set_error (error, - G_DBUS_ERROR, - G_DBUS_ERROR_SERVICE_UNKNOWN, - "The name %s was not provided by any .service files", name); - } - g_object_unref (ping_message); + return _g_kdbus_send_Ping(worker, name, error); } else { - SyntheticReplyData *data; - - data = g_new0 (SyntheticReplyData, 1); - - data->worker = worker; - data->message = g_object_ref (message); - - g_main_context_invoke (worker->context, _g_kdbus_StartServiceByName_helper, data); + GTask *task; + task = g_task_new (worker, + NULL, + (GAsyncReadyCallback) _g_kdbus_send_Ping_finish, + g_object_ref(message)); + g_task_set_task_data (task, message, NULL); + g_task_run_in_thread (task, _g_kdbus_send_Ping_thread); + g_object_unref (task); + return G_BUS_START_SERVICE_REPLY_SUCCESS; } } else - status = G_BUS_START_SERVICE_REPLY_ALREADY_RUNNING; - - return status; + { + return G_BUS_START_SERVICE_REPLY_ALREADY_RUNNING; + } } @@ -3739,19 +3740,6 @@ check_result_to_error_reply (GDBusMessage *message, } #endif -#ifdef LIBDBUSPOLICY -static void -send_error_message (GKDBusWorker *worker, - GDBusMessage *message) -{ - SyntheticReplyData *reply_data; - reply_data = g_new0 (SyntheticReplyData, 1); - reply_data->worker = worker; - reply_data->message = message; - g_main_context_invoke (worker->context, deliver_synthetic_reply, reply_data); -} -#endif - /* * _g_kdbus_send */ @@ -3931,7 +3919,7 @@ _g_kdbus_send (GKDBusWorker *worker, } else { - send_error_message (worker, access_error_message); + send_synthetic_message (worker, access_error_message); } goto out; -- 2.7.4