1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
/*
* Copyright (C) 2011 Canonical Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Authored by Alex Launi <alex.launi@canonical.com>
*
*/
using GLib;
using Config;
namespace Unity.MusicLens {
static Application? app = null;
static MusicStoreScopeProxy? daemon = null;
/* Check if a given well known DBus is owned.
* WARNING: This does sync IO! */
public static bool dbus_name_has_owner (string name)
{
try {
bool has_owner;
DBusConnection bus = Bus.get_sync (BusType.SESSION);
Variant result = bus.call_sync ("org.freedesktop.DBus",
"/org/freedesktop/dbus",
"org.freedesktop.DBus",
"NameHasOwner",
new Variant ("(s)", name),
new VariantType ("(b)"),
DBusCallFlags.NO_AUTO_START,
-1);
result.get ("(b)", out has_owner);
return has_owner;
} catch (Error e) {
warning ("Unable to decide whether '%s' is running: %s", name, e.message);
}
return false;
}
public static int main (string[] args)
{
GLib.Environment.set_prgname ("unity-musicstore-daemon");
/* Sort up locale to get translations but also sorting and
* punctuation right */
GLib.Intl.textdomain (Config.PACKAGE);
GLib.Intl.bindtextdomain (Config.PACKAGE, Config.LOCALEDIR);
GLib.Intl.bind_textdomain_codeset (Config.PACKAGE, "UTF-8");
GLib.Intl.setlocale(GLib.LocaleCategory.ALL, "");
/* Workaround for https://bugzilla.gnome.org/show_bug.cgi?id=640714
* GApplication.register() call owns our DBus name in a sync manner
* making it race against GDBus' worker thread to export our
* objects on the bus before/after owning our name and receiving
* method calls on our objects (which may not yet be up!)*/
if (dbus_name_has_owner ("com.canonical.Unity.Scope.MusicStore"))
{
print ("Another instance of the UbuntuOne Music Daemon " +
"already appears to be running.\nBailing out.\n");
return 2;
}
/* Now register our DBus objects *before* acquiring the name!
* See above for reasons */
daemon = new MusicStoreScopeProxy ();
/* Use GApplication directly for single instance app functionality */
app = new Application ("com.canonical.Unity.Scope.MusicStore",
ApplicationFlags.IS_SERVICE);
try {
app.register ();
} catch (Error e) {
/* FIXME: We get this error if another daemon is already running,
* but it uses a generic error so we can't detect this reliably... */
print ("Failed to start music daemon: %s\n", e.message);
return 1;
}
if (app.get_is_remote ())
{
print ("Another instance of the Unity Music Daemon " +
"already appears to be running.\nBailing out.\n");
return 2;
}
/* Hold()ing the app makes sure the GApplication doesn't exit */
app.hold();
return app.run ();
}
} /* namespace */
|