Package: gwibber-service
Version: 3.0.0.1-2.2
Severity: important
Tags: patch upstream

Dear Maintainer,

I noticed that sometimes gwibber generates multiple notifications for a
single update. I quickly figured out that issue was dbus starting
multiple gwibber-service instances because a race condition in service
startup. When I looked around I saw some Ubuntu bug report having
similar issues with their indicator. I don't know if there is any more
issues that are caused by the race condition.

I have made a proposed fix to gwibber code and dbu service configuration
to avoid the race condition in startup. The fix is simple refactoring
dbus interface to be under single service name that allows dbus to
provide atomic single service startup functionality for gwibber-service.

I checked upstream code that same bug still exists in the latest
development version. But I could easily compile the latest version in
Sid so I decided to first cook a patch for the debian package. I will
today forward port my changes for upstream inclusion.

Attached patch will require also changes to packaging because it reduces
.service files to only two.

-- System Information:
Debian Release: 7.0
  APT prefers unstable
  APT policy: (500, 'unstable'), (500, 'testing')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 3.2.0-4-amd64 (SMP w/4 CPU cores)
Locale: LANG=en_GB.utf8, LC_CTYPE=en_GB.utf8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages gwibber-service depends on:
ii  python                    2.7.3-3
ii  python-dbus               1.1.1-1
ii  python-egenix-mxdatetime  3.2.5-1
ii  python-gnomekeyring       2.32.0+dfsg-2+b1
ii  python-imaging            1.1.7-4
ii  python-notify             0.1.1-3
ii  python-oauth              1.0.1-3
ii  python-pycurl             7.19.0-5
ii  python-simplejson         2.6.2-1
ii  python-support            1.0.15
ii  python-xdg                0.19-4

Versions of packages gwibber-service recommends:
ii  gwibber-service-facebook  3.0.0.1-2.2
ii  gwibber-service-identica  3.0.0.1-2.2
ii  gwibber-service-twitter   3.0.0.1-2.2
ii  python-indicate           0.6.92-1
ii  python-libproxy           0.3.1-5.1

gwibber-service suggests no packages.

-- no debconf information
>From 66a327840fedca095961a2b8360450fa6099cbd3 Mon Sep 17 00:00:00 2001
From: Pauli Nieminen <suok...@gmail.com>
Date: Sat, 15 Dec 2012 08:51:31 +0200
Subject: [PATCH] fix dbus service startup not to start multiple instances

gwibber-service process can be started multiple times by dbus for each
service file. If previous startup hadn't yet had time to register the
com.Gwibber.Connection second instance will be able start duplicate
instance.

To avoid dealing with the startup race condition we can use single
service file to provide all services making dbus handle correctly single
gwibber-service instance per user login.

Signed-off-by: Pauli Nieminen <suok...@gmail.com>
---
 MANIFEST.in                        |    2 +-
 com.Gwibber.Accounts.service       |    3 ---
 com.Gwibber.Connection.service     |    3 ---
 com.Gwibber.Searches.service       |    3 ---
 com.Gwibber.Service.service        |    3 ---
 com.Gwibber.Streams.service        |    3 ---
 com.Gwibber.URLShorten.service     |    3 ---
 com.Gwibber.service                |    3 +++
 gwibber/lib/__init__.py            |    2 +-
 gwibber/microblog/dispatcher.py    |    8 ++++----
 gwibber/microblog/storage.py       |    8 ++++----
 gwibber/microblog/util/__init__.py |    8 ++++----
 setup.py                           |    2 +-
 13 files changed, 18 insertions(+), 33 deletions(-)
 delete mode 100644 com.Gwibber.Accounts.service
 delete mode 100644 com.Gwibber.Connection.service
 delete mode 100644 com.Gwibber.Searches.service
 delete mode 100644 com.Gwibber.Service.service
 delete mode 100644 com.Gwibber.Streams.service
 delete mode 100644 com.Gwibber.URLShorten.service
 create mode 100644 com.Gwibber.service

diff --git a/MANIFEST.in b/MANIFEST.in
index ee6d6b5..ea23713 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,6 +1,6 @@
 include AUTHORS COPYING INSTALL README
 include MANIFEST.in MANIFEST
-include com.Gwibber.*.service
+include com.Gwibber.service
 include com.GwibberClient.service
 include po/*
 include ui/*
diff --git a/com.Gwibber.Accounts.service b/com.Gwibber.Accounts.service
deleted file mode 100644
index b9ead43..0000000
--- a/com.Gwibber.Accounts.service
+++ /dev/null
@@ -1,3 +0,0 @@
-[D-BUS Service]
-Name=com.Gwibber.Accounts
-Exec=/usr/bin/gwibber-service
diff --git a/com.Gwibber.Connection.service b/com.Gwibber.Connection.service
deleted file mode 100644
index 07020fa..0000000
--- a/com.Gwibber.Connection.service
+++ /dev/null
@@ -1,3 +0,0 @@
-[D-BUS Service]
-Name=com.Gwibber.Connection
-Exec=/usr/bin/gwibber-service
diff --git a/com.Gwibber.Searches.service b/com.Gwibber.Searches.service
deleted file mode 100644
index b641b37..0000000
--- a/com.Gwibber.Searches.service
+++ /dev/null
@@ -1,3 +0,0 @@
-[D-BUS Service]
-Name=com.Gwibber.Searches
-Exec=/usr/bin/gwibber-service
diff --git a/com.Gwibber.Service.service b/com.Gwibber.Service.service
deleted file mode 100644
index 86f3ed8..0000000
--- a/com.Gwibber.Service.service
+++ /dev/null
@@ -1,3 +0,0 @@
-[D-BUS Service]
-Name=com.Gwibber.Service
-Exec=/usr/bin/gwibber-service
diff --git a/com.Gwibber.Streams.service b/com.Gwibber.Streams.service
deleted file mode 100644
index 94e80a7..0000000
--- a/com.Gwibber.Streams.service
+++ /dev/null
@@ -1,3 +0,0 @@
-[D-BUS Service]
-Name=com.Gwibber.Streams
-Exec=/usr/bin/gwibber-service
diff --git a/com.Gwibber.URLShorten.service b/com.Gwibber.URLShorten.service
deleted file mode 100644
index d24ee9c..0000000
--- a/com.Gwibber.URLShorten.service
+++ /dev/null
@@ -1,3 +0,0 @@
-[D-BUS Service]
-Name=com.Gwibber.URLShorten
-Exec=/usr/bin/gwibber-service
diff --git a/com.Gwibber.service b/com.Gwibber.service
new file mode 100644
index 0000000..86f3ed8
--- /dev/null
+++ b/com.Gwibber.service
@@ -0,0 +1,3 @@
+[D-BUS Service]
+Name=com.Gwibber.Service
+Exec=/usr/bin/gwibber-service
diff --git a/gwibber/lib/__init__.py b/gwibber/lib/__init__.py
index ba2afc3..342df85 100644
--- a/gwibber/lib/__init__.py
+++ b/gwibber/lib/__init__.py
@@ -15,7 +15,7 @@ class GwibberPublic:
 
     def getbus(self, name):
         obj = self.bus.get_object(
-            "com.Gwibber.%s" % name,
+            "com.Gwibber.Service",
             "/com/gwibber/%s" % name,
             follow_name_owner_changes=True)
         
diff --git a/gwibber/microblog/dispatcher.py b/gwibber/microblog/dispatcher.py
index d4a09ee..4bb4d33 100644
--- a/gwibber/microblog/dispatcher.py
+++ b/gwibber/microblog/dispatcher.py
@@ -801,7 +801,7 @@ class ConnectionMonitor(dbus.service.Object):
 
   def __init__(self):
     self.bus = dbus.SessionBus()
-    bus_name = dbus.service.BusName("com.Gwibber.Connection", bus=self.bus)
+    bus_name = dbus.service.BusName("com.Gwibber.Service", bus=self.bus)
     dbus.service.Object.__init__(self, bus_name, self.__dbus_object_path__)
 
     self.sysbus = dbus.SystemBus()
@@ -856,7 +856,7 @@ class URLShorten(dbus.service.Object):
 
   def __init__(self):
     self.bus = dbus.SessionBus()
-    bus_name = dbus.service.BusName("com.Gwibber.URLShorten", bus=self.bus)
+    bus_name = dbus.service.BusName("com.Gwibber.Service", bus=self.bus)
     dbus.service.Object.__init__(self, bus_name, self.__dbus_object_path__)
 
   @dbus.service.method("com.Gwibber.URLShorten", in_signature="s", out_signature="s")
@@ -866,7 +866,7 @@ class URLShorten(dbus.service.Object):
     example:
             import dbus
             url = "http://www.example.com/this/is/a/long/url";
-            obj = dbus.SessionBus().get_object("com.Gwibber.URLShorten", "/com/gwibber/URLShorten")
+            obj = dbus.SessionBus().get_object("com.Gwibber.Service", "/com/gwibber/URLShorten")
             shortener = dbus.Interface(obj, "com.Gwibber.URLShorten")
             short_url = shortener.Shorten(url)
     """
@@ -890,7 +890,7 @@ class Translate(dbus.service.Object):
 
   def __init__(self):
     self.bus = dbus.SessionBus()
-    bus_name = dbus.service.BusName("com.Gwibber.Translate", bus=self.bus)
+    bus_name = dbus.service.BusName("com.Gwibber.Service", bus=self.bus)
     dbus.service.Object.__init__(self, bus_name, self.__dbus_object_path__)
 
   @dbus.service.method("com.Gwibber.Translate", in_signature="sss", out_signature="s")
diff --git a/gwibber/microblog/storage.py b/gwibber/microblog/storage.py
index 24e42b1..c4e03de 100644
--- a/gwibber/microblog/storage.py
+++ b/gwibber/microblog/storage.py
@@ -13,7 +13,7 @@ class MessageManager(dbus.service.Object):
 
   def __init__(self, db):
     self.bus = dbus.SessionBus()
-    bus_name = dbus.service.BusName("com.Gwibber.Messages", bus=self.bus)
+    bus_name = dbus.service.BusName("com.Gwibber.Service", bus=self.bus)
     dbus.service.Object.__init__(self, bus_name, self.__dbus_object_path__)
     
     self.db = db
@@ -80,7 +80,7 @@ class SearchManager(dbus.service.Object):
 
   def __init__(self, db):
     self.bus = dbus.SessionBus()
-    bus_name = dbus.service.BusName("com.Gwibber.Searches", bus=self.bus)
+    bus_name = dbus.service.BusName("com.Gwibber.Service", bus=self.bus)
     dbus.service.Object.__init__(self, bus_name, self.__dbus_object_path__)
     self.db = db
 
@@ -145,7 +145,7 @@ class StreamManager(dbus.service.Object):
 
   def __init__(self, db):
     self.bus = dbus.SessionBus()
-    bus_name = dbus.service.BusName("com.Gwibber.Streams", bus=self.bus)
+    bus_name = dbus.service.BusName("com.Gwibber.Service", bus=self.bus)
     dbus.service.Object.__init__(self, bus_name, self.__dbus_object_path__)
     self.db = db
 
@@ -247,7 +247,7 @@ class AccountManager(dbus.service.Object):
 
   def __init__(self, db):
     self.bus = dbus.SessionBus()
-    bus_name = dbus.service.BusName("com.Gwibber.Accounts", bus=self.bus)
+    bus_name = dbus.service.BusName("com.Gwibber.Service", bus=self.bus)
     dbus.service.Object.__init__(self, bus_name, self.__dbus_object_path__)
     self.db = db
 
diff --git a/gwibber/microblog/util/__init__.py b/gwibber/microblog/util/__init__.py
index f73cf7a..2d31a36 100644
--- a/gwibber/microblog/util/__init__.py
+++ b/gwibber/microblog/util/__init__.py
@@ -178,15 +178,15 @@ except:
   can_notify = False
 
 
-def getbus(path, address="com.Gwibber"):
+def getbus(path, interface="com.Gwibber"):
   if not path.startswith("/"):
     path = "/com/gwibber/%s" % path
     if len(path.split('gwibber/')[1]) > 1:
-      address = "com.Gwibber.%s" % path.split('wibber/')[1]
+      interface = "com.Gwibber.%s" % path.split('wibber/')[1]
   bus = dbus.SessionBus()
-  obj = bus.get_object(address, path,
+  obj = bus.get_object("com.Gwibber.Service", path,
       follow_name_owner_changes = True)
-  return dbus.Interface(obj, address)
+  return dbus.Interface(obj, interface)
 
 def service_is_running(name):
   return name in dbus.Interface(dbus.SessionBus().get_object(
diff --git a/setup.py b/setup.py
index 35086bf..0aaaf47 100644
--- a/setup.py
+++ b/setup.py
@@ -83,7 +83,7 @@ setup(name="gwibber",
     ('share/gwibber/ui', ['ui/progress.gif']),
     ('share/gwibber/ui', ['ui/gwibber.svg']),
     ('share/pixmaps', ['ui/gwibber.svg']),
-    ('share/dbus-1/services', glob("com.Gwibber.*.service")),
+    ('share/dbus-1/services', ["com.Gwibber.service"]),
     ('share/dbus-1/services', ['com.GwibberClient.service']),
     ('share/gwibber/ui/icons/breakdance', glob("ui/icons/breakdance/*.png")),
     ('share/gwibber/ui/icons/breakdance', glob("ui/icons/breakdance/*.svg")),
-- 
1.7.10.4

Reply via email to