Receiving signals on Linux

Hi,

In an attempt to let Task Coach shut down nicely on Linux I let the
application register for SIGTERM and SIGHUP.

    def registerSignalHandlers(self):
        signal.signal(signal.SIGTERM, self.onSIGTERM)
        if hasattr(signal, 'SIGHUP'):
            signal.signal(signal.SIGHUP, self.onSIGHUP) # pylint:
disable-msg=E1101

    def onSIGTERM(self, *args): # pylint: disable-msg=W0613
        ''' onSIGTERM is called when the process receives a TERM signal. '''
        # Give the user time to save the file:
        self.mainwindow.quit()

    def onSIGHUP(self, *args): # pylint: disable-msg=W0613
        ''' onSIGHUP is called when the process receives a HUP signal,
            typically when the user logs out. '''
        # No time to pop up dialogs, force quit:
        self.mainwindow.quit(force=True)

When I send a TERM signal to a running instance (kill -TERM <pid>),
the signal is only delivered when I hover my mouse over the
application. So apparently, the mainloop needs to do something (e.g.
processing a mouse movement) for it to be able to receive the signal.
Is there anything I can do to make the application also respond to the
signal while it is idle?

Thanks, Frank

Signals are not delivered to the Python handlers until control returns to a Python block of code. IOW, if the app is sitting inside the MainLoop in the C++ code there will be no Python signal handler called until some Python code is executed.

IIRC, this is due to how Python deals with signals. The C signal handler in the signal extension module simply sets a flag to indicate the the signal happened. Then in the main Python byte-code evaluator the flag is checked every N byte-codes and if it's set then the Python signal handler function is called.

···

On 1/13/10 1:07 PM, Frank Niessink wrote:

Hi,

In an attempt to let Task Coach shut down nicely on Linux I let the
application register for SIGTERM and SIGHUP.

     def registerSignalHandlers(self):
         signal.signal(signal.SIGTERM, self.onSIGTERM)
         if hasattr(signal, 'SIGHUP'):
             signal.signal(signal.SIGHUP, self.onSIGHUP) # pylint:
disable-msg=E1101

     def onSIGTERM(self, *args): # pylint: disable-msg=W0613
         ''' onSIGTERM is called when the process receives a TERM signal. '''
         # Give the user time to save the file:
         self.mainwindow.quit()

     def onSIGHUP(self, *args): # pylint: disable-msg=W0613
         ''' onSIGHUP is called when the process receives a HUP signal,
             typically when the user logs out. '''
         # No time to pop up dialogs, force quit:
         self.mainwindow.quit(force=True)

When I send a TERM signal to a running instance (kill -TERM<pid>),
the signal is only delivered when I hover my mouse over the
application. So apparently, the mainloop needs to do something (e.g.
processing a mouse movement) for it to be able to receive the signal.
Is there anything I can do to make the application also respond to the
signal while it is idle?

--
Robin Dunn
Software Craftsman

So that suggests that setting a PyTimer every second or so should do
it right? (Frank experiments....). Yes it does. Thanks!

Cheers, Frank

···

2010/1/13 Robin Dunn <robin@alldunn.com>:

Signals are not delivered to the Python handlers until control returns to a
Python block of code. IOW, if the app is sitting inside the MainLoop in the
C++ code there will be no Python signal handler called until some Python
code is executed.

IIRC, this is due to how Python deals with signals. The C signal handler in
the signal extension module simply sets a flag to indicate the the signal
happened. Then in the main Python byte-code evaluator the flag is checked
every N byte-codes and if it's set then the Python signal handler function
is called.