-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixup atexit handling #35
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
import os | ||
import sys | ||
import atexit | ||
from ctypes import * | ||
from tempfile import NamedTemporaryFile | ||
|
||
|
@@ -10,7 +11,10 @@ | |
__all__ = ['dbLoadDatabase', 'iocInit', 'interactive_ioc'] | ||
|
||
|
||
epicsExit = imports.epicsExit | ||
# tie in epicsAtExit() to interpreter lifecycle | ||
@atexit.register | ||
def epicsAtPyExit(): | ||
imports.epicsExitCallAtExits() | ||
|
||
|
||
def iocInit(dispatcher=None): | ||
|
@@ -36,17 +40,24 @@ def iocInit(dispatcher=None): | |
imports.iocInit() | ||
|
||
|
||
def safeEpicsExit(): | ||
def safeEpicsExit(code=0): | ||
'''Calls epicsExit() after ensuring Python exit handlers called.''' | ||
if hasattr(sys, 'exitfunc'): | ||
if hasattr(sys, 'exitfunc'): # py 2.x | ||
try: | ||
# Calling epicsExit() will bypass any atexit exit handlers, so call | ||
# them explicitly now. | ||
sys.exitfunc() | ||
finally: | ||
# Make sure we don't try the exit handlers more than once! | ||
del sys.exitfunc | ||
epicsExit() | ||
|
||
elif hasattr(atexit, '_run_exitfuncs'): # py 3.x | ||
atexit._run_exitfuncs() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need to do the same dance as above with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not as I read it. |
||
|
||
# calls epicsExitCallAtExits() | ||
# and then OS exit() | ||
imports.epicsExit(code) | ||
epicsExit = safeEpicsExit | ||
|
||
# The following identifiers will be exported to interactive shell. | ||
command_names = [] | ||
|
@@ -233,10 +244,10 @@ def call_f(*args): | |
# Hacked up exit object so that when soft IOC framework sends us an exit command | ||
# we actually exit. | ||
class Exiter: | ||
def __repr__(self): | ||
safeEpicsExit() | ||
def __call__(self): | ||
safeEpicsExit() | ||
def __repr__(self): # hack to exit when "called" with no parenthesis | ||
sys.exit(0) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess this will make There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
def __call__(self, code=0): | ||
sys.exit(code) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why aren't we calling There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm guessing you answered this above in #35 (comment) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hopefully :) |
||
|
||
exit = Exiter() | ||
command_names.append('exit') | ||
|
@@ -305,7 +316,12 @@ def interactive_ioc(context = {}, call_exit = True): | |
# This suppresses irritating exit message introduced by Python3. Alas, | ||
# this option is only available in Python 3.6! | ||
interact_args = dict(exitmsg = '') | ||
code.interact(local = dict(exports, **context), **interact_args) | ||
try: | ||
code.interact(local = dict(exports, **context), **interact_args) | ||
except SystemExit as e: | ||
if call_exit: | ||
safeEpicsExit(e.code) | ||
raise | ||
|
||
if call_exit: | ||
safeEpicsExit() | ||
safeEpicsExit(0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops.
Looks like this was my mistake, back in commit c9548f6