diff --git a/src/bitmessagemain.py b/src/bitmessagemain.py index aae46f2c..f67f6619 100755 --- a/src/bitmessagemain.py +++ b/src/bitmessagemain.py @@ -255,10 +255,13 @@ class Main: def daemonize(self): if os.fork(): exit(0) + shared.thisapp.lock() # relock os.umask(0) os.setsid() if os.fork(): exit(0) + shared.thisapp.lock() # relock + shared.thisapp.lockPid = None # indicate we're the final child sys.stdout.flush() sys.stderr.flush() si = file('/dev/null', 'r') diff --git a/src/singleton.py b/src/singleton.py index a3a77fd7..8bf7ed01 100644 --- a/src/singleton.py +++ b/src/singleton.py @@ -23,6 +23,7 @@ class singleinstance: self.initialized = False self.counter = 0 self.daemon = daemon + self.lockPid = None self.lockfile = os.path.normpath(os.path.join(shared.appdata, 'singleton%s.lock' % flavor_id)) if not self.daemon and not shared.curses: @@ -30,6 +31,14 @@ class singleinstance: import bitmessageqt bitmessageqt.init() + self.lock() + + self.initialized = True + atexit.register(self.cleanup) + + def lock(self): + if self.lockPid is None: + self.lockPid = os.getpid() if sys.platform == 'win32': try: # file already exists, we try to remove (in case previous execution was interrupted) @@ -46,18 +55,19 @@ class singleinstance: else: # non Windows self.fp = open(self.lockfile, 'w') try: - fcntl.lockf(self.fp, fcntl.LOCK_EX | fcntl.LOCK_NB) + if self.daemon and self.lockPid != os.getpid(): + fcntl.lockf(self.fp, fcntl.LOCK_EX) # wait for parent to finish + else: + fcntl.lockf(self.fp, fcntl.LOCK_EX | fcntl.LOCK_NB) + self.lockPid = os.getpid() except IOError: print 'Another instance of this application is already running' sys.exit(-1) - self.initialized = True - atexit.register(self.cleanup) def cleanup(self): if not self.initialized: return - self.counter += 1 - if self.daemon and self.counter < 3: + if self.daemon and self.lockPid == os.getpid(): # these are the two initial forks while daemonizing return print "Cleaning up lockfile"