Commit f309134e authored by Victor Stinner's avatar Victor Stinner

Issue #11393: fix usage of locks in faulthandler

 * faulthandler_cancel_dump_tracebacks_later() is responsible to set running
   to zero (so we don't need the volatile keyword anymore)
 * release locks if PyThread_start_new_thread() fails

assert(thread.running == 0) was wrong in a corner case
parent a4d4f1b4
...@@ -48,7 +48,7 @@ static struct { ...@@ -48,7 +48,7 @@ static struct {
int fd; int fd;
PY_TIMEOUT_T timeout_ms; /* timeout in microseconds */ PY_TIMEOUT_T timeout_ms; /* timeout in microseconds */
int repeat; int repeat;
volatile int running; int running;
PyInterpreterState *interp; PyInterpreterState *interp;
int exit; int exit;
/* released by parent thread when cancel request */ /* released by parent thread when cancel request */
...@@ -419,7 +419,6 @@ faulthandler_thread(void *unused) ...@@ -419,7 +419,6 @@ faulthandler_thread(void *unused)
/* The only way out */ /* The only way out */
PyThread_release_lock(thread.cancel_event); PyThread_release_lock(thread.cancel_event);
PyThread_release_lock(thread.join_event); PyThread_release_lock(thread.join_event);
thread.running = 0;
} }
static void static void
...@@ -431,8 +430,8 @@ faulthandler_cancel_dump_tracebacks_later(void) ...@@ -431,8 +430,8 @@ faulthandler_cancel_dump_tracebacks_later(void)
} }
/* Wait for thread to join */ /* Wait for thread to join */
PyThread_acquire_lock(thread.join_event, 1); PyThread_acquire_lock(thread.join_event, 1);
assert(thread.running == 0);
PyThread_release_lock(thread.join_event); PyThread_release_lock(thread.join_event);
thread.running = 0;
Py_CLEAR(thread.file); Py_CLEAR(thread.file);
} }
...@@ -486,6 +485,8 @@ faulthandler_dump_traceback_later(PyObject *self, ...@@ -486,6 +485,8 @@ faulthandler_dump_traceback_later(PyObject *self,
thread.running = 1; thread.running = 1;
if (PyThread_start_new_thread(faulthandler_thread, NULL) == -1) { if (PyThread_start_new_thread(faulthandler_thread, NULL) == -1) {
thread.running = 0; thread.running = 0;
PyThread_release_lock(thread.join_event);
PyThread_release_lock(thread.cancel_event);
Py_CLEAR(thread.file); Py_CLEAR(thread.file);
PyErr_SetString(PyExc_RuntimeError, PyErr_SetString(PyExc_RuntimeError,
"unable to start watchdog thread"); "unable to start watchdog thread");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment