From b93375dd0997195221c24eb3d246df02cbbfc999 Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 25 Aug 2009 21:41:32 +0000 Subject: [PATCH] fixes for obscure bugs --- panda/src/downloader/httpChannel.cxx | 3 +++ panda/src/downloader/httpClient.h | 6 ++--- panda/src/pipeline/thread.cxx | 33 ++++++++++++++++++++++------ 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/panda/src/downloader/httpChannel.cxx b/panda/src/downloader/httpChannel.cxx index c34702c03c..65b9036094 100644 --- a/panda/src/downloader/httpChannel.cxx +++ b/panda/src/downloader/httpChannel.cxx @@ -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; } diff --git a/panda/src/downloader/httpClient.h b/panda/src/downloader/httpClient.h index 52d7e6fcbd..98369dedea 100644 --- a/panda/src/downloader/httpClient.h +++ b/panda/src/downloader/httpClient.h @@ -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); diff --git a/panda/src/pipeline/thread.cxx b/panda/src/pipeline/thread.cxx index aeb56867b2..2af54facdd 100644 --- a/panda/src/pipeline/thread.cxx +++ b/panda/src/pipeline/thread.cxx @@ -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 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