fixes for obscure bugs

This commit is contained in:
David Rose 2009-08-25 21:41:32 +00:00
parent 81363c4ba9
commit b93375dd09
3 changed files with 32 additions and 10 deletions

View File

@ -1998,6 +1998,9 @@ run_reading_header() {
bool HTTPChannel::
run_start_direct_file_read() {
_state = S_read_header;
if (!open_download_file()) {
return false;
}
return false;
}

View File

@ -128,9 +128,9 @@ PUBLISHED:
void clear_expected_servers();
PT(HTTPChannel) make_channel(bool persistent_connection);
PT(HTTPChannel) post_form(const URLSpec &url, const string &body);
PT(HTTPChannel) get_document(const URLSpec &url);
PT(HTTPChannel) get_header(const URLSpec &url);
BLOCKING PT(HTTPChannel) post_form(const URLSpec &url, const string &body);
BLOCKING PT(HTTPChannel) get_document(const URLSpec &url);
BLOCKING PT(HTTPChannel) get_header(const URLSpec &url);
INLINE static string base64_encode(const string &s);
INLINE static string base64_decode(const string &s);

View File

@ -334,10 +334,27 @@ call_python_func(PyObject *function, PyObject *args) {
// using true OS-level threading. PyGILState enforces policies
// like only one thread state per OS-level thread, which is not
// true in the case of SIMPLE_THREADS.
// For some reason I don't fully understand, I'm getting a crash
// when I clean up old PyThreadState objects with
// PyThreadState_Delete(). It appears that the thread state is
// still referenced somewhere at the time I call delete, and the
// crash occurs because I've deleted an active pointer.
// Storing these pointers in a vector for permanent recycling
// seems to avoid this problem. I wish I understood better what's
// going wrong, but I guess this workaround will do.
static pvector<PyThreadState *> thread_states;
PyThreadState *orig_thread_state = PyThreadState_Get();
PyInterpreterState *istate = orig_thread_state->interp;
PyThreadState *new_thread_state = PyThreadState_New(istate);
PyThreadState *new_thread_state;
if (thread_states.empty()) {
new_thread_state = PyThreadState_New(istate);
} else {
new_thread_state = thread_states.back();
thread_states.pop_back();
}
PyThreadState_Swap(new_thread_state);
// Call the user's function.
@ -360,8 +377,9 @@ call_python_func(PyObject *function, PyObject *args) {
PyErr_Print();
PyThreadState_Swap(orig_thread_state);
PyThreadState_Clear(new_thread_state);
PyThreadState_Delete(new_thread_state);
thread_states.push_back(new_thread_state);
//PyThreadState_Clear(new_thread_state);
//PyThreadState_Delete(new_thread_state);
PyErr_Restore(exc, val, tb);
@ -372,9 +390,10 @@ call_python_func(PyObject *function, PyObject *args) {
} else {
// No exception. Restore the thread state normally.
PyThreadState_Swap(orig_thread_state);
PyThreadState_Clear(new_thread_state);
PyThreadState_Delete(new_thread_state);
PyThreadState *state = PyThreadState_Swap(orig_thread_state);
thread_states.push_back(new_thread_state);
//PyThreadState_Clear(new_thread_state);
//PyThreadState_Delete(new_thread_state);
}
#else // SIMPLE_THREADS