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 nobody
Recipients
Date 2004-05-11.19:52:04
SpamBayes Score
Marked as misclassified
Message-id
In-reply-to
Content
Logged In: NO 

I agree, the original patch I submitted is horribly
ham-fisted because it blocks all signals.  I'm kicking
myself for not forseeing the problems with SIGSEGV, SIGTERM,
etc.  as reported in 756924.

The original problem I was trying to fix was that the wrong
thread (i.e.: any thread but the main thread) would receive
the SIGINT and end up doing the longjmp() to the context
saved by the main thread.  Then we have two threads
executing on the main thread's stack which is a Bad Thing. 
With the way the readline support currently handles SIGINT
via setjmp()/longjmp(), you really want the main thread and
only the main thread to get the SIGINT and perform that
longjmp().

Would it be reasonable to block only SIGINT (and not other
signals) for all threads but the main thread?  That would
force SIGINT to be handled by the main thread and eliminate
the worry that the wrong thread will do the longjmp() into
the main thread's context in the readline code.

I agree with large parts of langmead's proposed approach to
fixing this, but I do have concerns about the combination of
these two parts:

* Remove the section of thread creation that blocks signals.

* Change readline.c to use more thread safe constructs where 
available (arrange so that the longjmp out of the signal handler
is only executed for the thread that is using readline, and use 
siglongjmp if available)

According to the book "Programming with Threads" by
Kleinman, Shah, and Smaalders:

"Asynchronously generated signals are sent to the process as
a whole where they may be serviced by any thread that has
the signal unmasked.  If more than one thread is able to
receive a signal sent to the process, only one is chosen."

If we leave SIGINT unmasked on all threads, then the signal
handler will need to check the thread ID, and if not the
main thread, use pthread_kill(main_thread, SIGINT) to defer
the work to the main thread. In that sense, it'd be simpler
to block SIGINT in all threads and force the system to route
the SIGINT to the main thread directly.  Of course if a
particular threads implementation doesn't have the desired
asynchronous signal routing behavior, maybe leaving SIGINT
unmasked and using the pthread_kill(main_thread, SIGINT)
technique could work around that.

So to sum up, I'm in complete agreement with unblocking most
if not all signals in other threads and with langmead's
proposals to leverage the benefits provided by sigaction()
and siglongjmp() when possible.  I have one question though.
 Would it be reasonable to force SIGINT to be handled only
by the main thread, or is there a need for Python threads
other than the main thread to handle/receive SIGINT?  If the
latter then the setjmp()/longjmp() mechanism currently used
in the readline module is going to be problematic.
History
Date User Action Args
2007-08-23 14:14:05adminlinkissue756924 messages
2007-08-23 14:14:05admincreate