[postr: 3/8] Eliminate race conditions in PyUnique.



commit 88be7c77f9e1e17ae9b063d17497173bc3660f93
Author: Karl Mikaelsson <derfian lysator liu se>
Date:   Wed May 12 23:09:06 2010 +0200

    Eliminate race conditions in PyUnique.
    
    A race condition was present in the pyunique code, where several
    applications could be started at the same time, each trying to register
    the DBus objects at the same time. This is solved by requiring the
    application to have registered a special DBus name ("lock") before they
    can move on. Credits to Mathias Hasselmann for inspiration and DBus
    magic hints.

 src/PyUnique.py |   16 ++++++++++++++++
 1 files changed, 16 insertions(+), 0 deletions(-)
---
diff --git a/src/PyUnique.py b/src/PyUnique.py
index 55a93bd..4458f7d 100644
--- a/src/PyUnique.py
+++ b/src/PyUnique.py
@@ -26,6 +26,7 @@ import dbus.service
 from dbus.mainloop.glib import DBusGMainLoop
 from gtk import gdk
 import logging
+import time
 
 # Set the glib main loop as the default main loop for dbus
 #
@@ -105,6 +106,19 @@ class UniqueApp(gobject.GObject):
         # TODO: Find out what the startup_id is meant to be.
         self._startup_id = startup_id
         self.sess_bus = dbus.SessionBus()
+        lock = "org.gtk.PyUnique.lock"
+
+        # Acquire dbus "lock" - I don't want multiple processes
+        # starting at once.
+        while self.sess_bus.request_name(lock) not in [dbus.bus.REQUEST_NAME_REPLY_PRIMARY_OWNER,
+                                                       dbus.bus.REQUEST_NAME_REPLY_ALREADY_OWNER]:
+            time.sleep(0.1)
+
+        # So when we've arrived here, we're sure to be the only
+        # process executing this. A FIXME would be that this lock is a
+        # global lock for all PyUnique applications that hasn't
+        # modified the lock string themselves. Perhaps we should
+        # incorporate self.name into the locking string?
 
         try:
             # Try to get the object of the already running UniqueApp
@@ -119,6 +133,8 @@ class UniqueApp(gobject.GObject):
             self.busname = dbus.service.BusName(self._name, self.sess_bus)
             self.busobj = UniqueDBusObject(self.sess_bus, "/Factory", self)
 
+        self.sess_bus.release_name(lock)
+
     def is_running(self):
         """ Is another UniqueApp instance running? """
         return self.get_property('is-running')



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]