Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 83 additions & 66 deletions src/bitmessagemain.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,10 +218,12 @@ def start(self):
sys.exit()
elif opt in ("-d", "--daemon"):
daemon = True
state.enableGUI = False # run without a UI
elif opt in ("-c", "--curses"):
state.curses = True
elif opt in ("-t", "--test"):
state.testmode = daemon = True
state.enableGUI = False # run without a UI

# is the application already running? If yes then exit.
shared.thisapp = singleinstance("", daemon)
Expand All @@ -241,15 +243,19 @@ def start(self):
state.dandelion = 0

helper_bootstrap.knownNodes()
# Start the address generation thread
addressGeneratorThread = addressGenerator()
addressGeneratorThread.daemon = True # close the main program even if there are threads left
addressGeneratorThread.start()

# Start the thread that calculates POWs
singleWorkerThread = singleWorker()
singleWorkerThread.daemon = True # close the main program even if there are threads left
singleWorkerThread.start()
# Not needed if objproc is disabled
if state.enableObjProc:

# Start the address generation thread
addressGeneratorThread = addressGenerator()
addressGeneratorThread.daemon = True # close the main program even if there are threads left
addressGeneratorThread.start()

# Start the thread that calculates POWs
singleWorkerThread = singleWorker()
singleWorkerThread.daemon = True # close the main program even if there are threads left
singleWorkerThread.start()

# Start the SQL thread
sqlLookup = sqlThread()
Expand All @@ -259,73 +265,84 @@ def start(self):
Inventory() # init
Dandelion() # init, needs to be early because other thread may access it early

# SMTP delivery thread
if daemon and BMConfigParser().safeGet("bitmessagesettings", "smtpdeliver", '') != '':
smtpDeliveryThread = smtpDeliver()
smtpDeliveryThread.start()
# Enable object processor and SMTP only if objproc enabled
if state.enableObjProc:

# SMTP delivery thread
if daemon and BMConfigParser().safeGet("bitmessagesettings", "smtpdeliver", '') != '':
smtpDeliveryThread = smtpDeliver()
smtpDeliveryThread.start()

# SMTP daemon thread
if daemon and BMConfigParser().safeGetBoolean("bitmessagesettings", "smtpd"):
smtpServerThread = smtpServer()
smtpServerThread.start()
# SMTP daemon thread
if daemon and BMConfigParser().safeGetBoolean("bitmessagesettings", "smtpd"):
smtpServerThread = smtpServer()
smtpServerThread.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.
objectProcessorThread.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.
objectProcessorThread.start()

# Start the cleanerThread
singleCleanerThread = singleCleaner()
singleCleanerThread.daemon = True # close the main program even if there are threads left
singleCleanerThread.start()

shared.reloadMyAddressHashes()
shared.reloadBroadcastSendersForWhichImWatching()
# Not needed if objproc disabled
if state.enableObjProc:
shared.reloadMyAddressHashes()
shared.reloadBroadcastSendersForWhichImWatching()

# API is also objproc dependent
if BMConfigParser().safeGetBoolean('bitmessagesettings', 'apienabled'):
try:
apiNotifyPath = BMConfigParser().get(
'bitmessagesettings', 'apinotifypath')
except:
apiNotifyPath = ''
if apiNotifyPath != '':
with shared.printLock:
print('Trying to call', apiNotifyPath)

call([apiNotifyPath, "startingUp"])
singleAPIThread = singleAPI()
singleAPIThread.daemon = True # close the main program even if there are threads left
singleAPIThread.start()

# start network components if networking is enabled
if state.enableNetwork:
BMConnectionPool()
asyncoreThread = BMNetworkThread()
asyncoreThread.daemon = True
asyncoreThread.start()
for i in range(BMConfigParser().getint("threads", "receive")):
receiveQueueThread = ReceiveQueueThread(i)
receiveQueueThread.daemon = True
receiveQueueThread.start()
announceThread = AnnounceThread()
announceThread.daemon = True
announceThread.start()
state.invThread = InvThread()
state.invThread.daemon = True
state.invThread.start()
state.addrThread = AddrThread()
state.addrThread.daemon = True
state.addrThread.start()
state.downloadThread = DownloadThread()
state.downloadThread.daemon = True
state.downloadThread.start()

connectToStream(1)

if BMConfigParser().safeGetBoolean('bitmessagesettings','upnp'):
import upnp
upnpThread = upnp.uPnPThread()
upnpThread.start()
else:
# Populate with hardcoded value (same as connectToStream above)
state.streamsInWhichIAmParticipating.append(1)

if BMConfigParser().safeGetBoolean('bitmessagesettings', 'apienabled'):
try:
apiNotifyPath = BMConfigParser().get(
'bitmessagesettings', 'apinotifypath')
except:
apiNotifyPath = ''
if apiNotifyPath != '':
with shared.printLock:
print('Trying to call', apiNotifyPath)

call([apiNotifyPath, "startingUp"])
singleAPIThread = singleAPI()
singleAPIThread.daemon = True # close the main program even if there are threads left
singleAPIThread.start()

BMConnectionPool()
asyncoreThread = BMNetworkThread()
asyncoreThread.daemon = True
asyncoreThread.start()
for i in range(BMConfigParser().getint("threads", "receive")):
receiveQueueThread = ReceiveQueueThread(i)
receiveQueueThread.daemon = True
receiveQueueThread.start()
announceThread = AnnounceThread()
announceThread.daemon = True
announceThread.start()
state.invThread = InvThread()
state.invThread.daemon = True
state.invThread.start()
state.addrThread = AddrThread()
state.addrThread.daemon = True
state.addrThread.start()
state.downloadThread = DownloadThread()
state.downloadThread.daemon = True
state.downloadThread.start()

connectToStream(1)

if BMConfigParser().safeGetBoolean('bitmessagesettings','upnp'):
import upnp
upnpThread = upnp.uPnPThread()
upnpThread.start()

if daemon == False and BMConfigParser().safeGetBoolean('bitmessagesettings', 'daemon') == False:
if daemon == False or state.enableGUI: # FIXME redundant?
if state.curses == False:
if not depends.check_pyqt():
sys.exit(
Expand Down
4 changes: 2 additions & 2 deletions src/class_singleCleaner.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def run(self):
# If we are running as a daemon then we are going to fill up the UI
# queue which will never be handled by a UI. We should clear it to
# save memory.
if shared.thisapp.daemon:
if shared.thisapp.daemon or not state.enableGUI: # FIXME redundant?
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, maybe just if not state.enableGUI:

queues.UISignalQueue.queue.clear()
if timeWeLastClearedInventoryAndPubkeysTables < int(time.time()) - 7380:
timeWeLastClearedInventoryAndPubkeysTables = int(time.time())
Expand Down Expand Up @@ -120,7 +120,7 @@ def run(self):
if "Errno 28" in str(err):
logger.fatal('(while receiveDataThread knownnodes.needToWriteKnownNodesToDisk) Alert: Your disk or data storage volume is full. ')
queues.UISignalQueue.put(('alert', (tr._translate("MainWindow", "Disk full"), tr._translate("MainWindow", 'Alert: Your disk or data storage volume is full. Bitmessage will now exit.'), True)))
if shared.thisapp.daemon:
if shared.thisapp.daemon or not state.enableGUI: # FIXME redundant?
os._exit(0)
shared.needToWriteKnownNodesToDisk = False

Expand Down
3 changes: 2 additions & 1 deletion src/helper_generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import traceback

import shared
import state
from debug import logger
import queues
import shutdown
Expand Down Expand Up @@ -66,7 +67,7 @@ def signal_handler(signal, frame):
"PyBitmessage", "MainThread"):
return
logger.error("Got signal %i", signal)
if shared.thisapp.daemon:
if shared.thisapp.daemon or not state.enableGUI: # FIXME redundant?
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this needed

shutdown.doCleanShutdown()
else:
allThreadTraceback(frame)
Expand Down
2 changes: 1 addition & 1 deletion src/shutdown.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def doCleanShutdown():
except Queue.Empty:
break

if shared.thisapp.daemon:
if shared.thisapp.daemon or not state.enableGUI: # FIXME redundant?
logger.info('Clean shutdown complete.')
shared.thisapp.cleanup()
os._exit(0)
Expand Down
8 changes: 8 additions & 0 deletions src/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@

shutdown = 0 #Set to 1 by the doCleanShutdown function. Used to tell the proof of work worker threads to exit.


# Component control flags - set on startup, do not change during runtime
# The defaults are for standalone GUI (default operating mode)
enableNetwork = True # enable network threads
enableObjProc = True # enable object processing threads
enableAPI = True # enable API (if configured)
enableGUI = True # enable GUI (QT or ncurses)
enableSTDIO = False # enable STDIO threads
curses = False

sqlReady = False # set to true by sqlTread when ready for processing
Expand Down