[issue36538] _thread.interrupt_main() no longer interrupts Lock.wait

2019-04-06 Thread Eryk Sun


Eryk Sun  added the comment:

Windows doesn't implement POSIX signals in the kernel, so 
_thread.interrupt_main (i.e. PyErr_SetInterrupt) can be useful as an 
abstraction. 

Currently PyErr_SetInterrupt (Modules/signalmodule.c) doesn't set our SIGINT 
event in Windows. It was suggested in issue 29926 to replace the trip_signal 
call with raise(SIGINT). That works for Windows -- as long as we're not 
concerned about emulating Ctrl+C exactly as if the user typed it in the console 
(if we're attached to a console). In POSIX, raise(SIGINT) won't interrupt the 
main thread if it's in a blocking system call, since it targets pthread_self(), 
so PyErr_SetInterrupt can instead call kill(getpid(), SIGINT), as you suggest, 
or pthread_kill(main_thread, SIGINT). 

3.8 adds signal.raise_signal (see issue 35568), so it's possible to implement 
this in pure Python. Either way, it would be nice to keep it as a 
cross-platform function, and hopefully make it public and documented.

Another option would be to enhance our Windows implementation of os.kill to 
more closely match POSIX kill(), such that os.kill(os.getpid(), signal.SIGINT) 
is implemented as raise(SIGINT). That would be a breaking change since 
currently it calls TerminateProcess (an abrupt termination like POSIX SIGKILL).

--
nosy: +eryksun

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue36538] _thread.interrupt_main() no longer interrupts Lock.wait

2019-04-05 Thread Gregory P. Smith


New submission from Gregory P. Smith :

In Python 2.7 our threading implementation was so poor that a thread join 
ultimately called our lock wait implementation that busy looped polling and 
sleeping to check for a lock acquisition success.  calling 
thread.interrupt_main() which is just PyErr_SetInterrupt() C API in disguise 
successfully broke out of that lock wait loop.

In Python 3 with our drastically improved threading implementation, a lock wait 
is a pthreads sem_timedwait() or sem_trywait() API call, blocking within the 
pthreads library or OS kernel.  PyErr_SetInterrupt() obviously has no effect on 
that.  Only an actual signal arriving can interrupt that.

Thus instead of code using _thread.interrupt_main() - in 2and3 compatible 
applications, six.moves._thread.interrupt_main() - they should instead write:

 os.kill(os.getpid(), signal.SIGINT)

Given that _thread is a private module making _thread.interrupt_main() a 
private API, do we need to keep it?  If we do, we should at least document this 
behavior and recommend actually sending the signal.  It is less capable of 
actually interrupting the main thread from some common blocking operations 
today.  Sending the signal seems like it would always be better.

--
assignee: docs@python
components: Documentation, Extension Modules, Library (Lib)
messages: 339518
nosy: docs@python, gregory.p.smith
priority: normal
severity: normal
stage: needs patch
status: open
title: _thread.interrupt_main() no longer interrupts Lock.wait
type: behavior
versions: Python 3.8

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com