Main process fixes
- handles old dialog versions better if using curses - can spawn SMTP delivery thread if configured (only when in daemon mode) - daemonized mode now works more like it's properly supposed to on unix (double fork etc). You may have to adjust your init scripts, when when using upstart for example you should now use "expect daemon" - daemon mode now cleanly shuts down when TERM/INT signal is received
This commit is contained in:
parent
e5c9e6d383
commit
4865659d72
|
@ -38,6 +38,7 @@ from class_outgoingSynSender import outgoingSynSender
|
|||
from class_singleListener import singleListener
|
||||
from class_singleWorker import singleWorker
|
||||
from class_addressGenerator import addressGenerator
|
||||
from class_smtpDeliver import smtpDeliver
|
||||
from debug import logger
|
||||
|
||||
# Helper Functions
|
||||
|
@ -153,16 +154,21 @@ class Main:
|
|||
_fixWinsock()
|
||||
|
||||
shared.daemon = daemon
|
||||
|
||||
# get curses flag
|
||||
shared.curses = False
|
||||
if '-c' in sys.argv:
|
||||
shared.curses = True
|
||||
|
||||
# is the application already running? If yes then exit.
|
||||
shared.thisapp = singleton.singleinstance("", daemon)
|
||||
|
||||
# get curses flag
|
||||
curses = False
|
||||
if '-c' in sys.argv:
|
||||
curses = True
|
||||
if daemon:
|
||||
with shared.printLock:
|
||||
print('Running as a daemon. Send TERM signal to end.')
|
||||
self.daemonize()
|
||||
|
||||
signal.signal(signal.SIGINT, helper_generic.signal_handler)
|
||||
# signal.signal(signal.SIGINT, signal.SIG_DFL)
|
||||
self.setSignalHandler()
|
||||
|
||||
helper_bootstrap.knownNodes()
|
||||
# Start the address generation thread
|
||||
|
@ -180,6 +186,11 @@ class Main:
|
|||
sqlLookup.daemon = False # DON'T close the main program even if there are threads left. The closeEvent should command this thread to exit gracefully.
|
||||
sqlLookup.start()
|
||||
|
||||
# SMTP delivery thread
|
||||
if daemon and shared.config.get("bitmessagesettings", "smtpdeliver", None):
|
||||
smtpDeliveryThread = smtpDeliver()
|
||||
smtpDeliveryThread.start()
|
||||
|
||||
# Start the thread that calculates POWs
|
||||
objectProcessorThread = objectProcessor()
|
||||
objectProcessorThread.daemon = False # DON'T close the main program even the thread remains. This thread checks the shutdown variable after processing each object.
|
||||
|
@ -221,7 +232,7 @@ class Main:
|
|||
upnpThread.start()
|
||||
|
||||
if daemon == False and shared.safeConfigGetBoolean('bitmessagesettings', 'daemon') == False:
|
||||
if curses == False:
|
||||
if shared.curses == False:
|
||||
if not depends.check_pyqt():
|
||||
print('PyBitmessage requires PyQt unless you want to run it as a daemon and interact with it using the API. You can download PyQt from http://www.riverbankcomputing.com/software/pyqt/download or by searching Google for \'PyQt Download\'. If you want to run in daemon mode, see https://bitmessage.org/wiki/Daemon')
|
||||
print('You can also run PyBitmessage with the new curses interface by providing \'-c\' as a commandline argument.')
|
||||
|
@ -230,22 +241,38 @@ class Main:
|
|||
import bitmessageqt
|
||||
bitmessageqt.run()
|
||||
else:
|
||||
if depends.check_curses():
|
||||
if True:
|
||||
# if depends.check_curses():
|
||||
print('Running with curses')
|
||||
import bitmessagecurses
|
||||
bitmessagecurses.runwrapper()
|
||||
else:
|
||||
shared.config.remove_option('bitmessagesettings', 'dontconnect')
|
||||
|
||||
if daemon:
|
||||
with shared.printLock:
|
||||
print('Running as a daemon. The main program should exit this thread.')
|
||||
else:
|
||||
with shared.printLock:
|
||||
print('Running as a daemon. You can use Ctrl+C to exit.')
|
||||
while True:
|
||||
time.sleep(20)
|
||||
|
||||
def daemonize(self):
|
||||
if os.fork():
|
||||
exit(0)
|
||||
os.umask(0)
|
||||
os.setsid()
|
||||
if os.fork():
|
||||
exit(0)
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
si = file('/dev/null', 'r')
|
||||
so = file('/dev/null', 'a+')
|
||||
se = file('/dev/null', 'a+', 0)
|
||||
os.dup2(si.fileno(), sys.stdin.fileno())
|
||||
os.dup2(so.fileno(), sys.stdout.fileno())
|
||||
os.dup2(se.fileno(), sys.stderr.fileno())
|
||||
|
||||
def setSignalHandler(self):
|
||||
signal.signal(signal.SIGINT, helper_generic.signal_handler)
|
||||
signal.signal(signal.SIGTERM, helper_generic.signal_handler)
|
||||
# signal.signal(signal.SIGINT, signal.SIG_DFL)
|
||||
|
||||
def stop(self):
|
||||
with shared.printLock:
|
||||
print('Stopping Bitmessage Deamon.')
|
||||
|
|
|
@ -2,6 +2,7 @@ import socket
|
|||
import sys
|
||||
from binascii import hexlify, unhexlify
|
||||
|
||||
from debug import logger
|
||||
import shared
|
||||
|
||||
def convertIntToString(n):
|
||||
|
@ -17,11 +18,10 @@ def convertIntToString(n):
|
|||
def convertStringToInt(s):
|
||||
return int(hexlify(s), 16)
|
||||
|
||||
|
||||
def signal_handler(signal, frame):
|
||||
logger.error("Got signal %i", signal)
|
||||
if shared.safeConfigGetBoolean('bitmessagesettings', 'daemon'):
|
||||
shared.doCleanShutdown()
|
||||
sys.exit(0)
|
||||
else:
|
||||
print 'Unfortunately you cannot use Ctrl+C when running the UI because the UI captures the signal.'
|
||||
|
||||
|
|
|
@ -21,10 +21,11 @@ class singleinstance:
|
|||
"""
|
||||
def __init__(self, flavor_id="", daemon=False):
|
||||
self.initialized = False
|
||||
self.counter = 0
|
||||
self.daemon = daemon
|
||||
self.lockfile = os.path.normpath(os.path.join(shared.appdata, 'singleton%s.lock' % flavor_id))
|
||||
|
||||
if not self.daemon:
|
||||
if not self.daemon and not shared.curses:
|
||||
# Tells the already running (if any) application to get focus.
|
||||
import bitmessageqt
|
||||
bitmessageqt.init()
|
||||
|
@ -55,6 +56,10 @@ class singleinstance:
|
|||
def cleanup(self):
|
||||
if not self.initialized:
|
||||
return
|
||||
self.counter += 1
|
||||
if self.daemon and self.counter < 3:
|
||||
# these are the two initial forks while daemonizing
|
||||
return
|
||||
print "Cleaning up lockfile"
|
||||
try:
|
||||
if sys.platform == 'win32':
|
||||
|
|
Reference in New Issue
Block a user