Cleanup lockfile on exit
singleton.py design was broken. Fixed Bitmessage#775
This commit is contained in:
parent
4f26bf1059
commit
24a2deed8f
|
@ -152,13 +152,11 @@ if shared.useVeryEasyProofOfWorkForTesting:
|
||||||
|
|
||||||
class Main:
|
class Main:
|
||||||
def start(self, daemon=False):
|
def start(self, daemon=False):
|
||||||
global thisapp
|
|
||||||
|
|
||||||
_fixWinsock()
|
_fixWinsock()
|
||||||
|
|
||||||
shared.daemon = daemon
|
shared.daemon = daemon
|
||||||
# is the application already running? If yes then exit.
|
# is the application already running? If yes then exit.
|
||||||
thisapp = singleton.singleinstance("", daemon)
|
shared.thisapp = singleton.singleinstance("", daemon)
|
||||||
|
|
||||||
# get curses flag
|
# get curses flag
|
||||||
curses = False
|
curses = False
|
||||||
|
|
|
@ -2842,6 +2842,7 @@ class MyForm(settingsmixin.SMainWindow):
|
||||||
|
|
||||||
self.statusBar().showMessage(_translate(
|
self.statusBar().showMessage(_translate(
|
||||||
"MainWindow", "All done. Closing user interface..."))
|
"MainWindow", "All done. Closing user interface..."))
|
||||||
|
shared.thisapp.cleanup()
|
||||||
os._exit(0)
|
os._exit(0)
|
||||||
|
|
||||||
# window close event
|
# window close event
|
||||||
|
|
|
@ -55,6 +55,7 @@ appdata = '' #holds the location of the application data storage directory
|
||||||
statusIconColor = 'red'
|
statusIconColor = 'red'
|
||||||
connectedHostsList = {} #List of hosts to which we are connected. Used to guarantee that the outgoingSynSender threads won't connect to the same remote node twice.
|
connectedHostsList = {} #List of hosts to which we are connected. Used to guarantee that the outgoingSynSender threads won't connect to the same remote node twice.
|
||||||
shutdown = 0 #Set to 1 by the doCleanShutdown function. Used to tell the proof of work worker threads to exit.
|
shutdown = 0 #Set to 1 by the doCleanShutdown function. Used to tell the proof of work worker threads to exit.
|
||||||
|
thisapp = None # singleton lock instance
|
||||||
alreadyAttemptedConnectionsList = {
|
alreadyAttemptedConnectionsList = {
|
||||||
} # This is a list of nodes to which we have already attempted a connection
|
} # This is a list of nodes to which we have already attempted a connection
|
||||||
alreadyAttemptedConnectionsListLock = threading.Lock()
|
alreadyAttemptedConnectionsListLock = threading.Lock()
|
||||||
|
@ -392,7 +393,7 @@ def isProofOfWorkSufficient(data,
|
||||||
return POW <= 2 ** 64 / (nonceTrialsPerByte*(len(data) + payloadLengthExtraBytes + ((TTL*(len(data)+payloadLengthExtraBytes))/(2 ** 16))))
|
return POW <= 2 ** 64 / (nonceTrialsPerByte*(len(data) + payloadLengthExtraBytes + ((TTL*(len(data)+payloadLengthExtraBytes))/(2 ** 16))))
|
||||||
|
|
||||||
def doCleanShutdown():
|
def doCleanShutdown():
|
||||||
global shutdown
|
global shutdown, thisapp
|
||||||
shutdown = 1 #Used to tell proof of work worker threads and the objectProcessorThread to exit.
|
shutdown = 1 #Used to tell proof of work worker threads and the objectProcessorThread to exit.
|
||||||
broadcastToSendDataQueues((0, 'shutdown', 'no data'))
|
broadcastToSendDataQueues((0, 'shutdown', 'no data'))
|
||||||
objectProcessorQueue.put(('checkShutdownVariable', 'no data'))
|
objectProcessorQueue.put(('checkShutdownVariable', 'no data'))
|
||||||
|
@ -440,6 +441,7 @@ def doCleanShutdown():
|
||||||
|
|
||||||
if safeConfigGetBoolean('bitmessagesettings','daemon'):
|
if safeConfigGetBoolean('bitmessagesettings','daemon'):
|
||||||
logger.info('Clean shutdown complete.')
|
logger.info('Clean shutdown complete.')
|
||||||
|
thisapp.cleanup()
|
||||||
os._exit(0)
|
os._exit(0)
|
||||||
|
|
||||||
# If you want to command all of the sendDataThreads to do something, like shutdown or send some data, this
|
# If you want to command all of the sendDataThreads to do something, like shutdown or send some data, this
|
||||||
|
|
|
@ -1,10 +1,16 @@
|
||||||
#! /usr/bin/env python
|
#! /usr/bin/env python
|
||||||
|
|
||||||
import sys
|
import atexit
|
||||||
import os
|
|
||||||
import errno
|
import errno
|
||||||
import shared
|
|
||||||
from multiprocessing import Process
|
from multiprocessing import Process
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import shared
|
||||||
|
|
||||||
|
try:
|
||||||
|
import fcntl # @UnresolvedImport
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
class singleinstance:
|
class singleinstance:
|
||||||
"""
|
"""
|
||||||
|
@ -14,9 +20,8 @@ class singleinstance:
|
||||||
which is under the Python Software Foundation License version 2
|
which is under the Python Software Foundation License version 2
|
||||||
"""
|
"""
|
||||||
def __init__(self, flavor_id="", daemon=False):
|
def __init__(self, flavor_id="", daemon=False):
|
||||||
import sys
|
|
||||||
self.initialized = False
|
self.initialized = False
|
||||||
self.daemon = daemon;
|
self.daemon = daemon
|
||||||
self.lockfile = os.path.normpath(os.path.join(shared.appdata, 'singleton%s.lock' % flavor_id))
|
self.lockfile = os.path.normpath(os.path.join(shared.appdata, 'singleton%s.lock' % flavor_id))
|
||||||
|
|
||||||
if not self.daemon:
|
if not self.daemon:
|
||||||
|
@ -38,7 +43,6 @@ class singleinstance:
|
||||||
print(e.errno)
|
print(e.errno)
|
||||||
raise
|
raise
|
||||||
else: # non Windows
|
else: # non Windows
|
||||||
import fcntl # @UnresolvedImport
|
|
||||||
self.fp = open(self.lockfile, 'w')
|
self.fp = open(self.lockfile, 'w')
|
||||||
try:
|
try:
|
||||||
fcntl.lockf(self.fp, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
fcntl.lockf(self.fp, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
||||||
|
@ -46,20 +50,20 @@ class singleinstance:
|
||||||
print 'Another instance of this application is already running'
|
print 'Another instance of this application is already running'
|
||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
self.initialized = True
|
self.initialized = True
|
||||||
|
atexit.register(self.cleanup)
|
||||||
|
|
||||||
def __del__(self):
|
def cleanup(self):
|
||||||
import sys
|
|
||||||
if not self.initialized:
|
if not self.initialized:
|
||||||
return
|
return
|
||||||
|
print "Cleaning up lockfile"
|
||||||
try:
|
try:
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
if hasattr(self, 'fd'):
|
if hasattr(self, 'fd'):
|
||||||
os.close(self.fd)
|
os.close(self.fd)
|
||||||
os.unlink(self.lockfile)
|
os.unlink(self.lockfile)
|
||||||
else:
|
else:
|
||||||
import fcntl # @UnresolvedImport
|
|
||||||
fcntl.lockf(self.fp, fcntl.LOCK_UN)
|
fcntl.lockf(self.fp, fcntl.LOCK_UN)
|
||||||
if os.path.isfile(self.lockfile):
|
if os.path.isfile(self.lockfile):
|
||||||
os.unlink(self.lockfile)
|
os.unlink(self.lockfile)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
sys.exit(-1)
|
pass
|
||||||
|
|
Reference in New Issue
Block a user