Commit bf7b9b47 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Have to reset more state in PyEval_ReInitThreads

We were having problems with spawning subprocesses from threads,
since the children would inherit the "wait for another thread to acquire
the gil" flag, but would not inherit the thread that would actually
try to acquire the gil; this would make the child hang.
parent 5a680f65
......@@ -425,22 +425,6 @@ void finishMainThread() {
// TODO maybe this is the place to wait for non-daemon threads?
}
extern "C" void PyEval_ReInitThreads() noexcept {
pthread_t current_thread = pthread_self();
assert(current_threads.count(pthread_self()));
auto it = current_threads.begin();
while (it != current_threads.end()) {
if (it->second->pthread_id == current_thread) {
++it;
} else {
it = current_threads.erase(it);
}
}
// TODO we should clean up all created PerThreadSets, such as the one used in the heap for thread-local-caches.
}
// For the "AllowThreads" regions, let's save the thread state at the beginning of the region.
// This means that the thread won't get interrupted by the signals we would otherwise need to
......@@ -484,6 +468,25 @@ static pthread_mutex_t gil = PTHREAD_MUTEX_INITIALIZER;
static std::atomic<int> threads_waiting_on_gil(0);
static pthread_cond_t gil_acquired = PTHREAD_COND_INITIALIZER;
extern "C" void PyEval_ReInitThreads() noexcept {
pthread_t current_thread = pthread_self();
assert(current_threads.count(pthread_self()));
auto it = current_threads.begin();
while (it != current_threads.end()) {
if (it->second->pthread_id == current_thread) {
++it;
} else {
it = current_threads.erase(it);
}
}
num_starting_threads = 0;
threads_waiting_on_gil = 0;
// TODO we should clean up all created PerThreadSets, such as the one used in the heap for thread-local-caches.
}
void acquireGLWrite() {
threads_waiting_on_gil++;
pthread_mutex_lock(&gil);
......
......@@ -1753,7 +1753,7 @@ extern "C" bool nonzero(Box* obj) {
if (func == NULL) {
ASSERT(isUserDefined(obj->cls) || obj->cls == classobj_cls || obj->cls == type_cls
|| isSubclass(obj->cls, Exception) || obj->cls == file_cls || obj->cls == traceback_cls
|| obj->cls == instancemethod_cls,
|| obj->cls == instancemethod_cls || obj->cls == module_cls,
"%s.__nonzero__", getTypeName(obj)); // TODO
// TODO should rewrite these?
......
# skip-if: '-n' in EXTRA_JIT_ARGS or '-O' in EXTRA_JIT_ARGS
# allow-warning: converting unicode literal to str
# Make sure that we can fork from a threaded environment
#
# Running this test with -n or -O has horrible performance, since
# we will freshly JIT all of the post-fork code after every fork.
import subprocess
import threading
def worker(id):
for i in xrange(100):
subprocess.check_call(["true"])
print "done"
threads = []
for i in xrange(4):
t = threading.Thread(target=worker, args=(i,))
threads.append(t)
t.start()
for t in threads:
t.join()
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