Browse Source

fixes for obscure bugs

David Rose 16 years ago
parent
commit
b93375dd09

+ 3 - 0
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;
 }
 

+ 3 - 3
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);

+ 26 - 7
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<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