summaryrefslogtreecommitdiff
path: root/Parser/myreadline.c
diff options
context:
space:
mode:
authorMichael W. Hudson <mwh@python.net>2004-07-07 17:44:12 +0000
committerMichael W. Hudson <mwh@python.net>2004-07-07 17:44:12 +0000
commit30ea2f223f5c0a85a13bd893063555a9f587cd6d (patch)
treed9ad0b824eb899d1163043d982dd7d961b11a263 /Parser/myreadline.c
parente3c330b42a5dbc64a254354e906885134a852949 (diff)
downloadcpython-git-30ea2f223f5c0a85a13bd893063555a9f587cd6d.tar.gz
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.
Diffstat (limited to 'Parser/myreadline.c')
-rw-r--r--Parser/myreadline.c41
1 files changed, 38 insertions, 3 deletions
diff --git a/Parser/myreadline.c b/Parser/myreadline.c
index fd2b4f4c33..ff9fc91ee9 100644
--- a/Parser/myreadline.c
+++ b/Parser/myreadline.c
@@ -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;
}