mirror of
https://github.com/python/cpython.git
synced 2025-09-26 10:19:53 +00:00
This closes patch:
[ 960406 ] unblock signals in threads although the changes do not correspond exactly to any patch attached to that report. Non-main threads no longer have all signals masked. A different interface to readline is used. The handling of signals inside calls to PyOS_Readline is now rather different. These changes are all a bit scary! Review and cross-platform testing much appreciated.
This commit is contained in:
parent
e3c330b42a
commit
30ea2f223f
10 changed files with 1576 additions and 3095 deletions
|
@ -19,6 +19,14 @@
|
|||
extern char* vms__StdioReadline(FILE *sys_stdin, FILE *sys_stdout, char *prompt);
|
||||
#endif
|
||||
|
||||
|
||||
PyThreadState* _PyOS_ReadlineTState;
|
||||
|
||||
#if WITH_THREAD
|
||||
#include "pythread.h"
|
||||
static PyThread_type_lock _PyOS_ReadlineLock = NULL;
|
||||
#endif
|
||||
|
||||
int (*PyOS_InputHook)(void) = NULL;
|
||||
|
||||
#ifdef RISCOS
|
||||
|
@ -73,10 +81,13 @@ my_fgets(char *buf, int len, FILE *fp)
|
|||
}
|
||||
#ifdef EINTR
|
||||
if (errno == EINTR) {
|
||||
if (PyOS_InterruptOccurred()) {
|
||||
return 1; /* Interrupt */
|
||||
int s;
|
||||
PyEval_RestoreThread(_PyOS_ReadlineTState);
|
||||
s = PyErr_CheckSignals();
|
||||
PyThreadState_Swap(NULL);
|
||||
if (s < 0) {
|
||||
return 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (PyOS_InterruptOccurred()) {
|
||||
|
@ -155,6 +166,13 @@ PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
|
|||
{
|
||||
char *rv;
|
||||
|
||||
if (_PyOS_ReadlineTState == PyThreadState_GET()) {
|
||||
PyErr_SetString(PyExc_RuntimeError,
|
||||
"can't re-enter readline");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
if (PyOS_ReadlineFunctionPointer == NULL) {
|
||||
#ifdef __VMS
|
||||
PyOS_ReadlineFunctionPointer = vms__StdioReadline;
|
||||
|
@ -162,8 +180,18 @@ PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
|
|||
PyOS_ReadlineFunctionPointer = PyOS_StdioReadline;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if WITH_THREAD
|
||||
if (_PyOS_ReadlineLock == NULL) {
|
||||
_PyOS_ReadlineLock = PyThread_allocate_lock();
|
||||
}
|
||||
#endif
|
||||
|
||||
_PyOS_ReadlineTState = PyThreadState_GET();
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
#if WITH_THREAD
|
||||
PyThread_acquire_lock(_PyOS_ReadlineLock, 1);
|
||||
#endif
|
||||
|
||||
/* This is needed to handle the unlikely case that the
|
||||
* interpreter is in interactive mode *and* stdin/out are not
|
||||
|
@ -176,5 +204,12 @@ PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
|
|||
rv = (*PyOS_ReadlineFunctionPointer)(sys_stdin, sys_stdout,
|
||||
prompt);
|
||||
Py_END_ALLOW_THREADS
|
||||
|
||||
#if WITH_THREAD
|
||||
PyThread_release_lock(_PyOS_ReadlineLock);
|
||||
#endif
|
||||
|
||||
_PyOS_ReadlineTState = NULL;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue