change order of thread cleanup to avoid python crash

This commit is contained in:
David Rose 2007-10-03 23:33:49 +00:00
parent 203c39ab7a
commit 3e4e3248e7
3 changed files with 19 additions and 13 deletions

View File

@ -45,7 +45,8 @@ init_thread_context(struct ThreadContext *context,
makecontext(&context->_ucontext, (void (*)())&begin_context, 2, thread_func, data);
}
void save_thread_context(struct ThreadContext *context,
void
save_thread_context(struct ThreadContext *context,
ContextFunction *next_context, void *data) {
/* getcontext requires us to use a volatile auto variable to
differentiate between pass 1 (immediate return) and pass 2
@ -297,7 +298,8 @@ init_thread_context(struct ThreadContext *context,
setup_context_1();
}
void save_thread_context(struct ThreadContext *context,
void
save_thread_context(struct ThreadContext *context,
ContextFunction *next_context, void *data) {
if (cs_setjmp(context->_jmp_context) != 0) {
/* We have just returned from longjmp. In this case, return from

View File

@ -33,13 +33,14 @@ PythonThread(PyObject *function, PyObject *args,
const string &name, const string &sync_name) :
Thread(name, sync_name)
{
_function = function;
Py_INCREF(_function);
_args = NULL;
_result = NULL;
_function = function;
if (!PyCallable_Check(_function)) {
nassert_raise("Invalid function passed to PythonThread constructor");
}
Py_INCREF(_function);
if (args == Py_None) {
// None means no arguments; create an empty tuple.
@ -113,7 +114,7 @@ thread_main() {
// thread state per OS-level thread, which is not true in the case
// of SIMPLE_THREADS.
PyThreadState *orig_thread_state = PyThreadState_Swap(NULL);
PyThreadState *orig_thread_state = PyThreadState_Get();
PyInterpreterState *istate = orig_thread_state->interp;
PyThreadState *new_thread_state = PyThreadState_New(istate);
PyThreadState_Swap(new_thread_state);

View File

@ -200,6 +200,14 @@ preempt(ThreadSimpleImpl *thread) {
////////////////////////////////////////////////////////////////////
void ThreadSimpleManager::
next_context() {
// Delete any threads that need it. We can't delete the current
// thread, though.
while (!_finished.empty() && _finished.front() != _current_thread) {
ThreadSimpleImpl *finished_thread = _finished.front();
_finished.pop_front();
unref_delete(finished_thread->_parent_obj);
}
// Mark the current thread's resume point.
#ifdef HAVE_PYTHON
@ -268,6 +276,7 @@ prepare_for_exit() {
next_context();
// Delete any remaining threads.
while (!_finished.empty() && _finished.front() != _current_thread) {
ThreadSimpleImpl *finished_thread = _finished.front();
_finished.pop_front();
@ -410,12 +419,6 @@ st_choose_next_context(void *data) {
////////////////////////////////////////////////////////////////////
void ThreadSimpleManager::
choose_next_context() {
while (!_finished.empty() && _finished.front() != _current_thread) {
ThreadSimpleImpl *finished_thread = _finished.front();
_finished.pop_front();
unref_delete(finished_thread->_parent_obj);
}
_current_thread = NULL;
double now = get_current_time();