Browse Source

Merge #1132: Make Qt shutdown gracefully on reactor stop.

cf37639 Make Qt shutdown gracefully on reactor stop. (Adam Gibson)
master
Adam Gibson 4 years ago
parent
commit
264b12a702
No known key found for this signature in database
GPG Key ID: 141001A1AF77F20B
  1. 2
      jmbase/jmbase/__init__.py
  2. 17
      jmbase/jmbase/twisted_utils.py
  3. 29
      scripts/joinmarket-qt.py

2
jmbase/jmbase/__init__.py

@ -12,7 +12,7 @@ from .support import (get_log, chunks, debug_silence, jmprint,
from .proof_of_work import get_pow, verify_pow
from .twisted_utils import (stop_reactor, is_hs_uri, get_tor_agent,
get_nontor_agent, JMHiddenService,
JMHTTPResource)
JMHTTPResource, set_custom_stop_reactor)
from .bytesprod import BytesProducer
from .commands import *

17
jmbase/jmbase/twisted_utils.py

@ -9,6 +9,9 @@ import txtorcon
from txtorcon.web import tor_agent
from txtorcon import TorControlProtocol, TorConfig
_custom_stop_reactor_is_set = False
custom_stop_reactor = None
# This removes `CONF_CHANGED` requests
# over the Tor control port, which aren't needed for our use case.
def patch_add_event_listener(self, evt, callback):
@ -70,7 +73,19 @@ class WhitelistContextFactory(object):
return CertificateOptions(verify=False)
return self.default_policy.creatorForNetloc(hostname, port)
def set_custom_stop_reactor(fn):
global _custom_stop_reactor_is_set
global custom_stop_reactor
_custom_stop_reactor_is_set = True
custom_stop_reactor = fn
def stop_reactor():
if not _custom_stop_reactor_is_set:
_stop_reactor()
else:
custom_stop_reactor()
def _stop_reactor():
""" The value of the bool `reactor.running`
does not reliably tell us whether the
reactor is running (!). There are startup
@ -83,8 +98,6 @@ def stop_reactor():
except ReactorNotRunning:
pass
def is_hs_uri(s):
x = wrapped_urlparse(s)
if x.hostname.endswith(".onion"):

29
scripts/joinmarket-qt.py

@ -55,7 +55,7 @@ donation_address_url = "https://bitcoinprivacy.me/joinmarket-donations"
#Version of this Qt script specifically
JM_GUI_VERSION = '27dev'
from jmbase import get_log, stop_reactor
from jmbase import get_log, stop_reactor, set_custom_stop_reactor
from jmbase.support import EXIT_FAILURE, utxo_to_utxostr,\
hextobin, JM_CORE_VERSION
import jmbitcoin as btc
@ -1623,9 +1623,20 @@ class JMMainWindow(QMainWindow):
self.reactor = reactor
self.initUI()
# a flag to indicate that shutdown should not
# depend on user input
self.unconditional_shutdown = False
def closeEvent(self, event):
quit_msg = "Are you sure you want to quit?"
reply = JMQtMessageBox(self, quit_msg, mbtype='question')
if self.unconditional_shutdown:
JMQtMessageBox(self,
"RPC connection is lost; shutting down.",
mbtype='crit',
title="Error")
reply = QMessageBox.Yes
else:
quit_msg = "Are you sure you want to quit?"
reply = JMQtMessageBox(self, quit_msg, mbtype='question')
if reply == QMessageBox.Yes:
event.accept()
if self.reactor.threadpool is not None:
@ -2413,6 +2424,18 @@ tabWidget.currentChanged.connect(onTabChange)
mainWindow.show()
reactor.runReturn()
# Qt does not stop automatically when we stop the qt5reactor, and
# also we don't want to close without warning the user;
# patch our stop_reactor method to include the necessary cleanup:
def qt_shutdown():
# checking ensures we only fire the close
# event once even if stop_reactor is called
# multiple times (which it often is):
if mainWindow.isVisible():
mainWindow.unconditional_shutdown = True
mainWindow.close()
set_custom_stop_reactor(qt_shutdown)
# Upon launching the app, ask the user to choose a wallet to open
mainWindow.openWallet()

Loading…
Cancel
Save