Rework the whole unused get/setExitCause machinery

It is basically unused by now. Rework to be able to make use of it
later, no functional changes.

Signed-off-by: Sebastian Spaeth <Sebastian@SSpaeth.de>
This commit is contained in:
Sebastian Spaeth 2011-10-27 17:23:43 +02:00
parent 8195d1410f
commit d992c66156
2 changed files with 31 additions and 43 deletions

View File

@ -109,15 +109,15 @@ def exitnotifymonitorloop(callback):
def threadexited(thread): def threadexited(thread):
"""Called when a thread exits.""" """Called when a thread exits."""
ui = getglobalui() ui = getglobalui()
if thread.getExitCause() == 'EXCEPTION': if thread.exit_exception:
if isinstance(thread.getExitException(), SystemExit): if isinstance(thread.exit_exception, SystemExit):
# Bring a SystemExit into the main thread. # Bring a SystemExit into the main thread.
# Do not send it back to UI layer right now. # Do not send it back to UI layer right now.
# Maybe later send it to ui.terminate? # Maybe later send it to ui.terminate?
raise SystemExit raise SystemExit
ui.threadException(thread) # Expected to terminate ui.threadException(thread) # Expected to terminate
sys.exit(100) # Just in case... sys.exit(100) # Just in case...
elif thread.getExitMessage() == 'SYNC_WITH_TIMER_TERMINATE': elif thread.exit_message == 'SYNC_WITH_TIMER_TERMINATE':
ui.terminate() ui.terminate()
# Just in case... # Just in case...
sys.exit(100) sys.exit(100)
@ -128,7 +128,10 @@ class ExitNotifyThread(Thread):
"""This class is designed to alert a "monitor" to the fact that a """This class is designed to alert a "monitor" to the fact that a
thread has exited and to provide for the ability for it to find out thread has exited and to provide for the ability for it to find out
why. All instances are made daemon threads (setDaemon(True), so we why. All instances are made daemon threads (setDaemon(True), so we
bail out when the mainloop dies.""" bail out when the mainloop dies.
The thread can set instance variables self.exit_message for a human
readable reason of the thread exit."""
profiledir = None profiledir = None
"""class variable that is set to the profile directory if required""" """class variable that is set to the profile directory if required"""
@ -137,6 +140,9 @@ class ExitNotifyThread(Thread):
# These are all child threads that are supposed to go away when # These are all child threads that are supposed to go away when
# the main thread is killed. # the main thread is killed.
self.setDaemon(True) self.setDaemon(True)
self.exit_message = None
self._exit_exc = None
self._exit_stacktrace = None
def run(self): def run(self):
global exitthreads global exitthreads
@ -156,49 +162,31 @@ class ExitNotifyThread(Thread):
pass pass
prof.dump_stats(os.path.join(ExitNotifyThread.profiledir, prof.dump_stats(os.path.join(ExitNotifyThread.profiledir,
"%s_%s.prof" % (self.threadid, self.getName()))) "%s_%s.prof" % (self.threadid, self.getName())))
except: except Exception, e:
self.setExitCause('EXCEPTION') # Thread exited with Exception, store it
if sys: tb = traceback.format_exc()
self.setExitException(sys.exc_info()[1]) self.set_exit_exception(e, tb)
tb = traceback.format_exc()
self.setExitStackTrace(tb)
else:
self.setExitCause('NORMAL')
if not hasattr(self, 'exitmessage'):
self.setExitMessage(None)
if exitthreads: if exitthreads:
exitthreads.put(self, True) exitthreads.put(self, True)
def setExitCause(self, cause): def set_exit_exception(self, exc, st=None):
self.exitcause = cause """Sets Exception and stacktrace of a thread, so that other
def getExitCause(self): threads can query its exit status"""
self._exit_exc = exc
self._exit_stacktrace = st
@property
def exit_exception(self):
"""Returns the cause of the exit, one of: """Returns the cause of the exit, one of:
'EXCEPTION' -- the thread aborted because of an exception Exception() -- the thread aborted with this exception
'NORMAL' -- normal termination.""" None -- normal termination."""
return self.exitcause return self._exit_exc
def setExitException(self, exc):
self.exitexception = exc @property
def getExitException(self): def exit_stacktrace(self):
"""If getExitCause() is 'EXCEPTION', holds the value from """Returns a string representing the stack trace if set"""
sys.exc_info()[1] for this exception.""" return self._exit_stacktrace
return self.exitexception
def setExitStackTrace(self, st):
self.exitstacktrace = st
def getExitStackTrace(self):
"""If getExitCause() is 'EXCEPTION', returns a string representing
the stack trace for this exception."""
return self.exitstacktrace
def setExitMessage(self, msg):
"""Sets the exit message to be fetched by a subsequent call to
getExitMessage. This message may be any object or type except
None."""
self.exitmessage = msg
def getExitMessage(self):
"""For any exit cause, returns the message previously set by
a call to setExitMessage(), or None if there was no such message
set."""
return self.exitmessage
@classmethod @classmethod
def set_profiledir(cls, directory): def set_profiledir(cls, directory):

View File

@ -493,7 +493,7 @@ class Blinkenlights(UIBase, CursesUtil):
# Request to quit. # Request to quit.
#TODO: this causes us to bail out in main loop when the thread exits #TODO: this causes us to bail out in main loop when the thread exits
#TODO: review and rework this mechanism. #TODO: review and rework this mechanism.
currentThread().setExitCause('EXCEPTION') currentThread().set_exit_exception(SystemExit("User requested shutdown"))
self.terminate() self.terminate()
try: try:
index = acctkeys.index(chr(key)) index = acctkeys.index(chr(key))