[telepathy-mission-control-5.12] telepathy-mission-control: Avoid race between Mission Control' s two names by having one wait for the other
Simon McVittie
smcv at kemper.freedesktop.org
Wed Aug 8 02:33:12 PDT 2012
Module: telepathy-mission-control
Branch: telepathy-mission-control-5.12
Commit: ad4b94ecd7768bd952cdcba51fd7039f564e6765
URL: http://cgit.freedesktop.org/telepathy/telepathy-mission-control/commit/?id=ad4b94ecd7768bd952cdcba51fd7039f564e6765
Author: Simon McVittie <simon.mcvittie at collabora.co.uk>
Date: Tue Aug 7 19:48:09 2012 +0100
Avoid race between Mission Control's two names by having one wait for the other
If you do:
dbus-send --dest=org.freedesktop.Telepathy.MissionControl5 \
--type=method_call --print-reply / org.freedesktop.DBus.Peer.Ping & \
dbus-send --dest=org.freedesktop.Telepathy.AccountManager \
--type=method_call --print-reply / org.freedesktop.DBus.Peer.Ping
then one or both of the calls will fail because the executable claims
one of its bus names, but can't get the other, and exits 1.
By making one wait for the other, we get the desired behaviour.
I've made activating MissionControl5 wait for AccountManager because
in MC's current implementation AccountManager is taken last.
Reviewed-by: Jonny Lamb <jonny.lamb at collabora.co.uk>
Bug: https://bugs.freedesktop.org/show_bug.cgi?id=53220
---
server/Makefile.am | 5 +-
...reedesktop.Telepathy.MissionControl5.service.in | 2 +-
util/wait-for-name.c | 87 ++++++++++++++++++--
3 files changed, 86 insertions(+), 8 deletions(-)
diff --git a/server/Makefile.am b/server/Makefile.am
index ba73450..eb74a3c 100644
--- a/server/Makefile.am
+++ b/server/Makefile.am
@@ -24,7 +24,10 @@ servicefile_DATA=org.freedesktop.Telepathy.MissionControl5.service \
org.freedesktop.Telepathy.AccountManager.service
%.service: %.service.in Makefile
- $(AM_V_GEN)sed -e 's![@]libexecdir[@]!$(libexecdir)!' $< > $@
+ $(AM_V_GEN)sed \
+ -e 's![@]libexecdir[@]!$(libexecdir)!' \
+ -e 's![@]bindir[@]!$(bindir)!' \
+ $< > $@
man8_MANS = mission-control-5.8
diff --git a/server/org.freedesktop.Telepathy.MissionControl5.service.in b/server/org.freedesktop.Telepathy.MissionControl5.service.in
index d91d4dd..51f4dc1 100644
--- a/server/org.freedesktop.Telepathy.MissionControl5.service.in
+++ b/server/org.freedesktop.Telepathy.MissionControl5.service.in
@@ -1,3 +1,3 @@
[D-BUS Service]
Name=org.freedesktop.Telepathy.MissionControl5
-Exec=@libexecdir@/mission-control-5
+Exec=@bindir@/mc-wait-for-name --activate org.freedesktop.Telepathy.AccountManager org.freedesktop.Telepathy.MissionControl5
diff --git a/util/wait-for-name.c b/util/wait-for-name.c
index af8bcdb..4679a18 100644
--- a/util/wait-for-name.c
+++ b/util/wait-for-name.c
@@ -4,14 +4,22 @@
* automatically (after a while) by the desktop session.
*
* Usage, in
- * $XDG_DATA_DIRS/dbus-1/services/org.freedesktop.Client.Something.service:
+ * $XDG_DATA_DIRS/dbus-1/services/....Client.Something.service:
*
* [D-BUS Service]
- * Name=org.freedesktop.Telepathy.Client.Something
- * Exec=/usr/lib/mission-control/mc-wait-for-name org.freedesktop.Telepathy.Client.Something
+ * Name=....Client.Something
+ * Exec=/usr/lib/telepathy/mc-wait-for-name ....Client.Something
+ *
+ * Alternatively, it can be used to activate something via an alternative
+ * name, e.g. in
+ * $XDG_DATA_DIRS/dbus-1/services/....AccountManager.service:
+ *
+ * [D-BUS Service]
+ * Name=....AccountManager
+ * Exec=/usr/lib/telepathy/mc-wait-for-name --activate ....MissionControl5 ....AccountManager
*
* Copyright (C) 2009 Nokia Corporation
- * Copyright (C) 2009 Collabora Ltd.
+ * Copyright (C) 2009, 2012 Collabora Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -41,7 +49,7 @@
#include <glib.h>
-#include <telepathy-glib/dbus.h>
+#include <telepathy-glib/telepathy-glib.h>
static int exit_status = EX_SOFTWARE;
static guint timeout_id = 0;
@@ -86,8 +94,48 @@ noc_cb (TpDBusDaemon *bus_daemon,
}
}
+static void
+start_service_cb (TpDBusDaemon *bus_daemon,
+ guint ret,
+ const GError *error,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ GMainLoop *loop = user_data;
+
+ if (error != NULL)
+ {
+ g_message ("%s", error->message);
+ g_main_loop_quit (loop);
+ exit_status = EX_TEMPFAIL;
+ }
+ else
+ {
+ switch (ret)
+ {
+ case 1: /* DBUS_START_REPLY_SUCCESS */
+ g_debug ("activated name successfully started");
+ break;
+
+ case 2: /* DBUS_START_REPLY_ALREADY_RUNNING */
+ g_debug ("activated name already running");
+ break;
+
+ default:
+ g_message ("ignoring unknown result from StartServiceByName: %u", ret);
+ break;
+ }
+ }
+}
+
#define WFN_TIMEOUT (5 * 60) /* 5 minutes */
+static gchar *activate = NULL;
+static GOptionEntry entries[] = {
+ { "activate", 0, 0, G_OPTION_ARG_STRING, &activate, "Activate NAME before waiting for the other name", "NAME" },
+ { NULL }
+};
+
int
main (int argc,
char **argv)
@@ -95,14 +143,33 @@ main (int argc,
TpDBusDaemon *bus_daemon;
GMainLoop *loop;
GError *error = NULL;
+ GOptionContext *context;
g_set_prgname ("mc-wait-for-name");
+ context = g_option_context_new ("- wait for a bus name");
+ g_option_context_add_main_entries (context, entries, NULL);
+
+ if (!g_option_context_parse (context, &argc, &argv, &error))
+ {
+ g_message ("%s", error->message);
+ g_error_free (error);
+ return EX_USAGE;
+ }
+
+ if (activate != NULL &&
+ !tp_dbus_check_valid_bus_name (activate, TP_DBUS_NAME_TYPE_WELL_KNOWN,
+ NULL))
+ {
+ g_message ("Not a valid bus name: %s", activate);
+ return EX_USAGE;
+ }
+
if (argc != 2 ||
!tp_dbus_check_valid_bus_name (argv[1], TP_DBUS_NAME_TYPE_WELL_KNOWN,
NULL))
{
- g_message ("Usage: mc-wait-for-name com.example.SomeBusName");
+ g_message ("Usage: mc-wait-for-name [OPTIONS] com.example.SomeBusName");
return EX_USAGE;
}
@@ -117,6 +184,14 @@ main (int argc,
}
loop = g_main_loop_new (NULL, FALSE);
+
+ if (activate != NULL)
+ {
+ tp_cli_dbus_daemon_call_start_service_by_name (bus_daemon, -1,
+ activate, 0 /* no flags */, start_service_cb, g_main_loop_ref (loop),
+ (GDestroyNotify) g_main_loop_unref, NULL);
+ }
+
tp_dbus_daemon_watch_name_owner (bus_daemon, argv[1],
noc_cb, g_main_loop_ref (loop), (GDestroyNotify) g_main_loop_unref);
More information about the telepathy-commits
mailing list