Commit 51d65601 authored by Kevin Modzelewski's avatar Kevin Modzelewski

While investigating fork() behavior, found another threading bug

We weren't able to exit if we had a thread running in the background,
since we released the GIL at the end of the C level main() and the
background thread would start running again after all the data structures
had been torn down.

Now, just keep holding the GIL as we exit.
parent 472aeb9c
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "asm_writing/assembler.h" #include "asm_writing/assembler.h"
#include "asm_writing/icinfo.h" #include "asm_writing/icinfo.h"
#include "core/threading.h"
namespace pyston { namespace pyston {
...@@ -432,7 +433,8 @@ public: ...@@ -432,7 +433,8 @@ public:
// This check isn't thread safe and should be fine to remove if it causes // This check isn't thread safe and should be fine to remove if it causes
// issues (along with the nvars/start_vars accounting) // issues (along with the nvars/start_vars accounting)
ASSERT(RewriterVar::nvars == start_vars, "%d %d", RewriterVar::nvars, start_vars); ASSERT(threading::threadWasStarted() || RewriterVar::nvars == start_vars, "%d %d", RewriterVar::nvars,
start_vars);
} }
Location getReturnDestination(); Location getReturnDestination();
......
...@@ -277,7 +277,14 @@ static void* _thread_start(void* _arg) { ...@@ -277,7 +277,14 @@ static void* _thread_start(void* _arg) {
return rtn; return rtn;
} }
static bool thread_was_started = false;
bool threadWasStarted() {
return thread_was_started;
}
intptr_t start_thread(void* (*start_func)(Box*, Box*, Box*), Box* arg1, Box* arg2, Box* arg3) { intptr_t start_thread(void* (*start_func)(Box*, Box*, Box*), Box* arg1, Box* arg2, Box* arg3) {
thread_was_started = true;
{ {
LOCK_REGION(&threading_lock); LOCK_REGION(&threading_lock);
num_starting_threads++; num_starting_threads++;
......
...@@ -28,6 +28,8 @@ class Box; ...@@ -28,6 +28,8 @@ class Box;
namespace threading { namespace threading {
bool threadWasStarted();
// returns a thread id (currently, the pthread_t id) // returns a thread id (currently, the pthread_t id)
intptr_t start_thread(void* (*start_func)(Box*, Box*, Box*), Box* arg1, Box* arg2, Box* arg3); intptr_t start_thread(void* (*start_func)(Box*, Box*, Box*), Box* arg1, Box* arg2, Box* arg3);
......
...@@ -93,7 +93,7 @@ int main(int argc, char** argv) { ...@@ -93,7 +93,7 @@ int main(int argc, char** argv) {
const char* fn = NULL; const char* fn = NULL;
threading::registerMainThread(); threading::registerMainThread();
threading::GLReadRegion _glock; threading::acquireGLRead();
{ {
Timer _t("for initCodegen"); Timer _t("for initCodegen");
...@@ -222,6 +222,11 @@ int main(int argc, char** argv) { ...@@ -222,6 +222,11 @@ int main(int argc, char** argv) {
threading::finishMainThread(); threading::finishMainThread();
// Acquire the GIL to make sure we stop the other threads, since we will tear down
// data structures they are potentially running on.
// Note: we will purposefully not release the GIL on exiting.
threading::promoteGL();
_t.split("joinRuntime"); _t.split("joinRuntime");
int rtncode = joinRuntime(); int rtncode = joinRuntime();
......
...@@ -915,7 +915,14 @@ Done: ...@@ -915,7 +915,14 @@ Done:
} }
extern "C" void PyOS_AfterFork(void) { extern "C" void PyOS_AfterFork(void) {
Py_FatalError("unimplemented"); // TODO CPython does a number of things after a fork:
// - clears pending signals
// - updates the cached "main_pid"
// - reinitialize and reacquire the GIL
// - reinitialize the import lock
// - change the definition of the main thread to the current thread
// - call threading._after_fork
// Also see PyEval_ReInitThreads
} }
extern "C" { extern "C" {
......
# Make sure that we can exit with threads running in the background.
from thread import start_new_thread
import time
counter = 0
def daemon_thread():
global counter
while True:
for i in xrange(100):
counter += 1
time.sleep(0.0)
start_new_thread(daemon_thread, ())
while counter < 100:
time.sleep(0.01)
print "exiting"
# exit without stopping the daemon 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