This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author jasonlowe
Recipients
Date 2004-05-12.13:54:35
SpamBayes Score
Marked as misclassified
Message-id
In-reply-to
Content
Logged In: YES 
user_id=56897

SIGINT is 'special' because that's the signal behind the
problems reported in bug 465673.  Given the readline
module's setjmp/longjmp mechanism to process SIGINT, we
simply cannot allow one thread to do the setjmp() and
another thread to do the longjmp() when it receives SIGINT.
 Without the setjmp/longjmp stuff, SIGINT is no more special
than any other asynchronous signal like SIGTERM, SIGUSR1,
etc.  It'd be great if we could get the desired behavior for
SIGINT out of the readline module without setjmp/longjmp,
but without help from the readline library I don't see an
easy way to do this.  The readline library insists on
continuing the readline() call after a SIGINT is handled,
and there doesn't appear to be any way to get it to abort
the current readline() call short of modifying the readline
library.

If we're stuck with the setjmp/longjmp mechanism, I think we
can solve the issues regarding readline() being called from
another thread and exec'd processes from threads by using
the pthread_kill() technique mentioned earlier.  The steps
would look something like this:

- Do not block any signals (including SIGINT) in any threads.

- When we initialize the readline module's jmp_buf via
setjmp(), save off the current thread ID.  Probably want to
check for existing ownership of jmp_buf and flag an error if
detected.

- When the readline module SIGINT handler is invoked, check
if the current thread owns jmp_buf.  If we are the owning
thread then execute the longjmp (or siglongjmp).  If we're
not the owning thread, then have the current thread execute
pthread_kill(jmp_buf_owner_thread, SIGINT) and little else.
 This will defer the SIGINT to the only thread that can
really process it correctly.

- Since SIGINT isn't blocked in any thread, processes exec'd
from threads should get the default behavior for SIGINT
rather than having it blocked.

The above algorithm has a race condition on thread
implementations where all threads receive SIGINT.  The race
can cause SIGINT to be processed more than once.  The
jmp_buf owning thread might finish the processing of SIGINT
before another thread starts its processing and re-sends
SIGINT to the jmp_buf owning thread.  If there's a way to
know via configure that we're on a thread implementation
that broadcasts SIGINT, we could #ifdef the code to use
something like the getpid() hack in signalmodule.c to do the
right thing.
History
Date User Action Args
2007-08-23 14:14:06adminlinkissue756924 messages
2007-08-23 14:14:06admincreate