def doCleanShutdown(): state.shutdown = 1 #Used to tell proof of work worker threads and the objectProcessorThread to exit. objectProcessorQueue.put(('checkShutdownVariable', 'no data')) for thread in threading.enumerate(): if thread.isAlive() and isinstance(thread, StoppableThread): thread.stopThread() UISignalQueue.put( ('updateStatusBar', 'Saving the knownNodes list of peers to disk...')) logger.info('Saving knownNodes list of peers to disk') saveKnownNodes() logger.info('Done saving knownNodes list of peers to disk') UISignalQueue.put(('updateStatusBar', 'Done saving the knownNodes list of peers to disk.')) logger.info('Flushing inventory in memory out to disk...') UISignalQueue.put(( 'updateStatusBar', 'Flushing inventory in memory out to disk. This should normally only take a second...' )) Inventory().flush() # Verify that the objectProcessor has finished exiting. It should have incremented the # shutdown variable from 1 to 2. This must finish before we command the sqlThread to exit. while state.shutdown == 1: time.sleep(.1) # This one last useless query will guarantee that the previous flush committed and that the # objectProcessorThread committed before we close the program. sqlQuery('SELECT address FROM subscriptions') logger.info('Finished flushing inventory.') sqlStoredProcedure('exit') # Wait long enough to guarantee that any running proof of work worker threads will check the # shutdown variable and exit. If the main thread closes before they do then they won't stop. time.sleep(.25) for thread in threading.enumerate(): if thread is not threading.currentThread() and isinstance( thread, StoppableThread): logger.debug("Waiting for thread %s", thread.name) thread.join() # flush queued for queue in (workerQueue, UISignalQueue, addressGeneratorQueue, objectProcessorQueue): while True: try: queue.get(False) queue.task_done() except Queue.Empty: break if shared.thisapp.daemon: logger.info('Clean shutdown complete.') shared.thisapp.cleanup() os._exit(0) else: logger.info('Core shutdown complete.') for thread in threading.enumerate(): logger.debug("Thread %s still running", thread.name)
def HandleDeleteAndVacuum(self, params): if not params: sqlStoredProcedure('deleteandvacuume') return 'done'
def accept(self): """A callback for accepted event of buttonBox (OK button pressed)""" # pylint: disable=too-many-branches,too-many-statements super(SettingsDialog, self).accept() if self.firstrun: self.config.remove_option('bitmessagesettings', 'dontconnect') self.config.set('bitmessagesettings', 'startonlogon', str(self.checkBoxStartOnLogon.isChecked())) self.config.set('bitmessagesettings', 'minimizetotray', str(self.checkBoxMinimizeToTray.isChecked())) self.config.set('bitmessagesettings', 'trayonclose', str(self.checkBoxTrayOnClose.isChecked())) self.config.set( 'bitmessagesettings', 'hidetrayconnectionnotifications', str(self.checkBoxHideTrayConnectionNotifications.isChecked())) self.config.set('bitmessagesettings', 'showtraynotifications', str(self.checkBoxShowTrayNotifications.isChecked())) self.config.set('bitmessagesettings', 'startintray', str(self.checkBoxStartInTray.isChecked())) self.config.set('bitmessagesettings', 'willinglysendtomobile', str(self.checkBoxWillinglySendToMobile.isChecked())) self.config.set('bitmessagesettings', 'useidenticons', str(self.checkBoxUseIdenticons.isChecked())) self.config.set('bitmessagesettings', 'replybelow', str(self.checkBoxReplyBelow.isChecked())) lang = str( self.languageComboBox.itemData( self.languageComboBox.currentIndex()).toString()) self.config.set('bitmessagesettings', 'userlocale', lang) self.parent.change_translation() if int(self.config.get('bitmessagesettings', 'port')) != int( self.lineEditTCPPort.text()): self.config.set('bitmessagesettings', 'port', str(self.lineEditTCPPort.text())) if not self.config.safeGetBoolean('bitmessagesettings', 'dontconnect'): self.net_restart_needed = True if self.checkBoxUPnP.isChecked() != self.config.safeGetBoolean( 'bitmessagesettings', 'upnp'): self.config.set('bitmessagesettings', 'upnp', str(self.checkBoxUPnP.isChecked())) if self.checkBoxUPnP.isChecked(): import upnp upnpThread = upnp.uPnPThread() upnpThread.start() proxytype_index = self.comboBoxProxyType.currentIndex() if proxytype_index == 0: if self._proxy_type and state.statusIconColor != 'red': self.net_restart_needed = True elif self.comboBoxProxyType.currentText() != self._proxy_type: self.net_restart_needed = True self.parent.statusbar.clearMessage() self.config.set( 'bitmessagesettings', 'socksproxytype', 'none' if self.comboBoxProxyType.currentIndex() == 0 else str( self.comboBoxProxyType.currentText())) if proxytype_index > 2: # last literal proxytype in ui start_proxyconfig() self.config.set('bitmessagesettings', 'socksauthentication', str(self.checkBoxAuthentication.isChecked())) self.config.set('bitmessagesettings', 'sockshostname', str(self.lineEditSocksHostname.text())) self.config.set('bitmessagesettings', 'socksport', str(self.lineEditSocksPort.text())) self.config.set('bitmessagesettings', 'socksusername', str(self.lineEditSocksUsername.text())) self.config.set('bitmessagesettings', 'sockspassword', str(self.lineEditSocksPassword.text())) self.config.set('bitmessagesettings', 'sockslisten', str(self.checkBoxSocksListen.isChecked())) if self.checkBoxOnionOnly.isChecked() \ and not self.config.safeGetBoolean('bitmessagesettings', 'onionservicesonly'): self.net_restart_needed = True self.config.set('bitmessagesettings', 'onionservicesonly', str(self.checkBoxOnionOnly.isChecked())) try: # Rounding to integers just for aesthetics self.config.set( 'bitmessagesettings', 'maxdownloadrate', str(int(float(self.lineEditMaxDownloadRate.text())))) self.config.set('bitmessagesettings', 'maxuploadrate', str(int(float(self.lineEditMaxUploadRate.text())))) except ValueError: QtGui.QMessageBox.about( self, _translate("MainWindow", "Number needed"), _translate( "MainWindow", "Your maximum download and upload rate must be numbers." " Ignoring what you typed.")) else: set_rates( self.config.safeGetInt('bitmessagesettings', 'maxdownloadrate'), self.config.safeGetInt('bitmessagesettings', 'maxuploadrate')) self.config.set( 'bitmessagesettings', 'maxoutboundconnections', str(int(float(self.lineEditMaxOutboundConnections.text())))) self.config.set('bitmessagesettings', 'namecoinrpctype', self.getNamecoinType()) self.config.set('bitmessagesettings', 'namecoinrpchost', str(self.lineEditNamecoinHost.text())) self.config.set('bitmessagesettings', 'namecoinrpcport', str(self.lineEditNamecoinPort.text())) self.config.set('bitmessagesettings', 'namecoinrpcuser', str(self.lineEditNamecoinUser.text())) self.config.set('bitmessagesettings', 'namecoinrpcpassword', str(self.lineEditNamecoinPassword.text())) self.parent.resetNamecoinConnection() # Demanded difficulty tab if float(self.lineEditTotalDifficulty.text()) >= 1: self.config.set( 'bitmessagesettings', 'defaultnoncetrialsperbyte', str( int( float(self.lineEditTotalDifficulty.text()) * defaults.networkDefaultProofOfWorkNonceTrialsPerByte))) if float(self.lineEditSmallMessageDifficulty.text()) >= 1: self.config.set( 'bitmessagesettings', 'defaultpayloadlengthextrabytes', str( int( float(self.lineEditSmallMessageDifficulty.text()) * defaults.networkDefaultPayloadLengthExtraBytes))) if self.comboBoxOpenCL.currentText().toUtf8() != self.config.safeGet( 'bitmessagesettings', 'opencl'): self.config.set('bitmessagesettings', 'opencl', str(self.comboBoxOpenCL.currentText())) queues.workerQueue.put(('resetPoW', '')) acceptableDifficultyChanged = False if (float(self.lineEditMaxAcceptableTotalDifficulty.text()) >= 1 or float(self.lineEditMaxAcceptableTotalDifficulty.text()) == 0): if self.config.get( 'bitmessagesettings', 'maxacceptablenoncetrialsperbyte' ) != str( int( float( self.lineEditMaxAcceptableTotalDifficulty.text()) * defaults.networkDefaultProofOfWorkNonceTrialsPerByte)): # the user changed the max acceptable total difficulty acceptableDifficultyChanged = True self.config.set( 'bitmessagesettings', 'maxacceptablenoncetrialsperbyte', str( int( float(self.lineEditMaxAcceptableTotalDifficulty. text()) * defaults. networkDefaultProofOfWorkNonceTrialsPerByte))) if (float(self.lineEditMaxAcceptableSmallMessageDifficulty.text()) >= 1 or float( self.lineEditMaxAcceptableSmallMessageDifficulty.text()) == 0): if self.config.get( 'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes' ) != str( int( float(self.lineEditMaxAcceptableSmallMessageDifficulty. text()) * defaults.networkDefaultPayloadLengthExtraBytes)): # the user changed the max acceptable small message difficulty acceptableDifficultyChanged = True self.config.set( 'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes', str( int( float(self. lineEditMaxAcceptableSmallMessageDifficulty. text()) * defaults.networkDefaultPayloadLengthExtraBytes))) if acceptableDifficultyChanged: # It might now be possible to send msgs which were previously # marked as toodifficult. Let us change them to 'msgqueued'. # The singleWorker will try to send them and will again mark # them as toodifficult if the receiver's required difficulty # is still higher than we are willing to do. sqlExecute("UPDATE sent SET status='msgqueued'" " WHERE status='toodifficult'") queues.workerQueue.put(('sendmessage', '')) stopResendingDefaults = False # UI setting to stop trying to send messages after X days/months # I'm open to changing this UI to something else if someone has a better idea. if self.lineEditDays.text() == '' and self.lineEditMonths.text() == '': # We need to handle this special case. Bitmessage has its # default behavior. The input is blank/blank self.config.set('bitmessagesettings', 'stopresendingafterxdays', '') self.config.set('bitmessagesettings', 'stopresendingafterxmonths', '') state.maximumLengthOfTimeToBotherResendingMessages = float('inf') stopResendingDefaults = True try: days = float(self.lineEditDays.text()) except ValueError: self.lineEditDays.setText("0") days = 0.0 try: months = float(self.lineEditMonths.text()) except ValueError: self.lineEditMonths.setText("0") months = 0.0 if days >= 0 and months >= 0 and not stopResendingDefaults: state.maximumLengthOfTimeToBotherResendingMessages = \ days * 24 * 60 * 60 + months * 60 * 60 * 24 * 365 / 12 if state.maximumLengthOfTimeToBotherResendingMessages < 432000: # If the time period is less than 5 hours, we give # zero values to all fields. No message will be sent again. QtGui.QMessageBox.about( self, _translate("MainWindow", "Will not resend ever"), _translate( "MainWindow", "Note that the time limit you entered is less" " than the amount of time Bitmessage waits for" " the first resend attempt therefore your" " messages will never be resent.")) self.config.set('bitmessagesettings', 'stopresendingafterxdays', '0') self.config.set('bitmessagesettings', 'stopresendingafterxmonths', '0') state.maximumLengthOfTimeToBotherResendingMessages = 0.0 else: self.config.set('bitmessagesettings', 'stopresendingafterxdays', str(days)) self.config.set('bitmessagesettings', 'stopresendingafterxmonths', str(months)) self.config.save() if self.net_restart_needed: self.net_restart_needed = False self.config.setTemp('bitmessagesettings', 'dontconnect', 'true') self.timer.singleShot( 5000, lambda: self.config.setTemp('bitmessagesettings', 'dontconnect', 'false')) self.parent.updateStartOnLogon() if (state.appdata != paths.lookupExeFolder() and self.checkBoxPortableMode.isChecked()): # If we are NOT using portable mode now but the user selected # that we should... # Write the keys.dat file to disk in the new location sqlStoredProcedure('movemessagstoprog') with open(paths.lookupExeFolder() + 'keys.dat', 'wb') as configfile: self.config.write(configfile) # Write the knownnodes.dat file to disk in the new location knownnodes.saveKnownNodes(paths.lookupExeFolder()) os.remove(state.appdata + 'keys.dat') os.remove(state.appdata + 'knownnodes.dat') previousAppdataLocation = state.appdata state.appdata = paths.lookupExeFolder() debug.resetLogging() try: os.remove(previousAppdataLocation + 'debug.log') os.remove(previousAppdataLocation + 'debug.log.1') except Exception: pass if (state.appdata == paths.lookupExeFolder() and not self.checkBoxPortableMode.isChecked()): # If we ARE using portable mode now but the user selected # that we shouldn't... state.appdata = paths.lookupAppdataFolder() if not os.path.exists(state.appdata): os.makedirs(state.appdata) sqlStoredProcedure('movemessagstoappdata') # Write the keys.dat file to disk in the new location self.config.save() # Write the knownnodes.dat file to disk in the new location knownnodes.saveKnownNodes(state.appdata) os.remove(paths.lookupExeFolder() + 'keys.dat') os.remove(paths.lookupExeFolder() + 'knownnodes.dat') debug.resetLogging() try: os.remove(paths.lookupExeFolder() + 'debug.log') os.remove(paths.lookupExeFolder() + 'debug.log.1') except Exception: pass
def doCleanShutdown(): state.shutdown = 1 #Used to tell proof of work worker threads and the objectProcessorThread to exit. #Stop sources of new threads for thread in threading.enumerate(): if type(thread).__name__ not in ('outgoingSynSender', 'singleListener'): continue thread.stopThread() thread.join() protocol.broadcastToSendDataQueues((0, 'shutdown', 'no data')) objectProcessorQueue.put(('checkShutdownVariable', 'no data')) for thread in threading.enumerate(): if thread.isAlive() and isinstance(thread, StoppableThread): thread.stopThread() UISignalQueue.put( ('updateStatusBar', 'Saving the knownNodes list of peers to disk...')) logger.info('Saving knownNodes list of peers to disk') saveKnownNodes() logger.info('Done saving knownNodes list of peers to disk') UISignalQueue.put(('updateStatusBar', 'Done saving the knownNodes list of peers to disk.')) logger.info('Flushing inventory in memory out to disk...') UISignalQueue.put(( 'updateStatusBar', 'Flushing inventory in memory out to disk. This should normally only take a second...' )) Inventory().flush() # Verify that the objectProcessor has finished exiting. It should have incremented the # shutdown variable from 1 to 2. This must finish before we command the sqlThread to exit. for thread in threading.enumerate(): if type(thread).__name__ != 'objectProcessor': continue thread.join() break # This will guarantee that the previous flush committed and that the # objectProcessorThread committed before we close the program. sqlStoredProcedure('commit') logger.info('Finished flushing inventory.') sqlStoredProcedure('exit') for thread in threading.enumerate(): if type(thread).__name__ != 'sqlThread': continue thread.join() break # Wait long enough to guarantee that any running proof of work worker threads will check the # shutdown variable and exit. If the main thread closes before they do then they won't stop. time.sleep(.25) for thread in threading.enumerate(): if isinstance(thread, sendDataThread): thread.sendDataThreadQueue.put((0, 'shutdown', 'no data')) if thread is not threading.currentThread() and isinstance( thread, StoppableThread) and not isinstance(thread, outgoingSynSender): logger.debug("Waiting for thread %s", thread.name) thread.join() # flush queued for queue in (workerQueue, UISignalQueue, addressGeneratorQueue, objectProcessorQueue): while True: try: queue.get(False) queue.task_done() except Queue.Empty: break logger.info('Clean shutdown complete.') for thread in threading.enumerate(): if thread is threading.currentThread(): continue logger.debug("Thread %s still running", thread.name) if BMConfigParser().safeGetBoolean('bitmessagesettings', 'daemon'): shared.thisapp.cleanup() os._exit(0)