From: sanghyeok.oh Date: Tue, 19 Feb 2019 06:47:41 +0000 (+0900) Subject: kdbus: modified to support asynchronous StartServiceByName X-Git-Tag: accepted/tizen/unified/20190715.111822~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0103b00208b9dd544d5795b993577a86714d1e94;p=platform%2Fupstream%2Fglib.git kdbus: modified to support asynchronous StartServiceByName Change-Id: I57c30fb86b1ec266037a4583ef64888ca92f2bc9 Signed-off-by: sanghyeok.oh --- diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c index 56ea38e..0c2844c 100755 --- a/gio/gdbusconnection.c +++ b/gio/gdbusconnection.c @@ -1462,7 +1462,7 @@ schedule_closed_unlocked (GDBusConnection *connection, * of the thread that @connection was constructed in. * * This is an asynchronous method. When the operation is finished, - * @callback will be invoked in the + * @callback will be invoked in the * [thread-default main context][g-main-context-push-thread-default] * of the thread you are calling this method from. You can * then call g_dbus_connection_close_finish() to get the result of the @@ -2200,7 +2200,7 @@ g_dbus_start_service_by_name (GDBusConnection *connection, #ifdef G_OS_UNIX if (connection->kdbus_worker) - return _g_kdbus_StartServiceByName (connection->kdbus_worker, name, flags, error); + return _g_kdbus_StartServiceByName (connection->kdbus_worker, name, flags, NULL, error); #endif result = g_dbus_connection_call_sync (connection, "org.freedesktop.DBus", "/", @@ -2665,7 +2665,7 @@ g_dbus_connection_send_message_with_reply_unlocked (GDBusConnection *connect * the operation fails with %G_IO_ERROR_INVALID_ARGUMENT. * * This is an asynchronous method. When the operation is finished, @callback - * will be invoked in the + * will be invoked in the * [thread-default main context][g-main-context-push-thread-default] * of the thread you are calling this method from. You can then call * g_dbus_connection_send_message_with_reply_finish() to get the result of the operation. @@ -4235,7 +4235,7 @@ is_signal_data_for_name_lost_or_acquired (SignalData *signal_data) * subscription is removed or %NULL * * Subscribes to signals on @connection and invokes @callback with a whenever - * the signal is received. Note that @callback will be invoked in the + * the signal is received. Note that @callback will be invoked in the * [thread-default main context][g-main-context-push-thread-default] * of the thread you are calling this method from. * @@ -6026,7 +6026,7 @@ obj_message_func (GDBusConnection *connection, * D-Bus interface that is described in @interface_info. * * Calls to functions in @vtable (and @user_data_free_func) will happen - * in the + * in the * [thread-default main context][g-main-context-push-thread-default] * of the thread you are calling this method from. * diff --git a/gio/gkdbus.c b/gio/gkdbus.c index 2b06396..cbc366a 100755 --- a/gio/gkdbus.c +++ b/gio/gkdbus.c @@ -1631,6 +1631,92 @@ _g_kdbus_GetConnectionSecurityLabel (GKDBusWorker *worker, return sec_label; } +typedef struct +{ + GKDBusWorker *worker; + GDBusMessage *message; +} SyntheticReplyData; + +static gboolean +deliver_synthetic_reply (gpointer user_data) +{ + SyntheticReplyData *data; + GKDBusWorker *worker; + GDBusMessage *message; + + data = user_data; + worker = data->worker; + message = data->message; + + (* worker->message_received_callback) (message, worker->user_data); + + g_object_unref (message); + g_free (data); + + return FALSE; +} + +static gboolean +_g_kdbus_StartServiceByName_helper (gpointer user_data) +{ + 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); + if (!ret) + { + gchar *dbus_error_name; + + 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)); + + 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); + + g_free (dbus_error_name); + g_error_free (local_error); + } + 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)); + } + + 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; +} /* < internal > * @@ -1646,6 +1732,7 @@ GBusStartServiceReplyFlags _g_kdbus_StartServiceByName (GKDBusWorker *worker, const gchar *name, guint32 flags, + GDBusMessage *message, GError **error) { GBusStartServiceReplyFlags status; @@ -1664,30 +1751,46 @@ _g_kdbus_StartServiceByName (GKDBusWorker *worker, if (!g_kdbus_NameHasOwner_internal (worker, name)) { - GDBusMessage *message; + gboolean ret; GDBusMessage *reply; - gint ret; + gboolean sync; reply = NULL; + status = G_BUS_START_SERVICE_REPLY_SUCCESS; + sync = message ? FALSE : TRUE; - message = g_dbus_message_new_method_call (name, "/", "org.freedesktop.DBus.Peer", "Ping"); - g_dbus_message_set_serial (message, -1); - - ret = _g_kdbus_send (worker, message, &reply, 25000, NULL, NULL); - if (!ret) + if (sync) { - g_set_error (error, - G_DBUS_ERROR, - G_DBUS_ERROR_SERVICE_UNKNOWN, - "The name %s was not provided by any .service files", name); - status = G_BUS_START_SERVICE_REPLY_ERROR; + 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); } else { - g_object_unref (reply); - status = G_BUS_START_SERVICE_REPLY_SUCCESS; + 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); } - g_object_unref (message); } else status = G_BUS_START_SERVICE_REPLY_ALREADY_RUNNING; @@ -3572,31 +3675,6 @@ compute_msg_size (GDBusMessage *message, return sizeof (struct kdbus_msg) + items_size; } -typedef struct -{ - GKDBusWorker *worker; - GDBusMessage *message; -} SyntheticReplyData; - -static gboolean -deliver_synthetic_reply (gpointer user_data) -{ - SyntheticReplyData *data; - GKDBusWorker *worker; - GDBusMessage *message; - - data = user_data; - worker = data->worker; - message = data->message; - - (* worker->message_received_callback) (message, worker->user_data); - - g_object_unref (message); - g_free (data); - - return FALSE; -} - #ifdef LIBDBUSPOLICY static GDBusMessage* create_access_error_reply (GDBusMessage *message, @@ -4160,14 +4238,20 @@ _g_kdbus_worker_send_message (GKDBusWorker *worker, #ifdef DBUS_DAEMON_EMULATION if (_is_message_to_dbus_daemon (message)) { - SyntheticReplyData *data; + GDBusMessage *reply = NULL; + reply = _dbus_daemon_synthetic_reply (worker, message, FALSE); - data = g_new0 (SyntheticReplyData, 1); + if (reply) + { + SyntheticReplyData *data; + + data = g_new0 (SyntheticReplyData, 1); - data->worker = worker; - data->message = _dbus_daemon_synthetic_reply (worker, message); + data->worker = worker; + data->message = reply; - g_main_context_invoke (worker->context, deliver_synthetic_reply, data); + g_main_context_invoke (worker->context, deliver_synthetic_reply, data); + } return TRUE; } @@ -4187,7 +4271,7 @@ _g_kdbus_worker_send_message_sync (GKDBusWorker *worker, #ifdef DBUS_DAEMON_EMULATION if (_is_message_to_dbus_daemon (message)) { - *out_reply = _dbus_daemon_synthetic_reply (worker, message); + *out_reply = _dbus_daemon_synthetic_reply (worker, message, TRUE); return TRUE; } #endif /* DBUS_DAEMON_EMULATION */ diff --git a/gio/gkdbus.h b/gio/gkdbus.h index a245f92..acbc0d5 100644 --- a/gio/gkdbus.h +++ b/gio/gkdbus.h @@ -163,6 +163,7 @@ gchar * _g_kdbus_GetConnectionSecurityLabel (GKDBusWork GBusStartServiceReplyFlags _g_kdbus_StartServiceByName (GKDBusWorker *worker, const gchar *name, guint32 flags, + GDBusMessage *message, GError **error); gboolean _g_kdbus_AddMatch (GKDBusWorker *worker, diff --git a/gio/gkdbusfakedaemon.c b/gio/gkdbusfakedaemon.c index c13bf49..04272f3 100644 --- a/gio/gkdbusfakedaemon.c +++ b/gio/gkdbusfakedaemon.c @@ -146,7 +146,8 @@ _is_message_to_dbus_daemon (GDBusMessage *message) */ GDBusMessage * _dbus_daemon_synthetic_reply (GKDBusWorker *worker, - GDBusMessage *message) + GDBusMessage *message, + gboolean sync) { GDBusMessage *reply; GVariant *reply_body; @@ -621,9 +622,18 @@ _dbus_daemon_synthetic_reply (GKDBusWorker *worker, g_variant_get (body, "(&su)", &name, &flags); - status = _g_kdbus_StartServiceByName (worker, name, flags, &local_error); + if (sync) + status = _g_kdbus_StartServiceByName (worker, name, flags, NULL, &local_error); + else + status = _g_kdbus_StartServiceByName (worker, name, flags, message, &local_error); + if (local_error == NULL) - reply_body = g_variant_new ("(u)", status); + { + if (status == G_BUS_START_SERVICE_REPLY_ALREADY_RUNNING || sync) + reply_body = g_variant_new ("(u)", status); + else + return NULL; + } } else g_set_error (&local_error, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, diff --git a/gio/gkdbusfakedaemon.h b/gio/gkdbusfakedaemon.h index 7378671..969b7b5 100644 --- a/gio/gkdbusfakedaemon.h +++ b/gio/gkdbusfakedaemon.h @@ -32,7 +32,8 @@ gboolean _is_message_to_dbus_daemon (GDBusMessage *message); GDBusMessage * _dbus_daemon_synthetic_reply (GKDBusWorker *worker, - GDBusMessage *message); + GDBusMessage *message, + gboolean sync); G_END_DECLS #endif /* __G_KDBUSFAKEDAEMON_H__ */