diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/easy.c | 5 | ||||
-rw-r--r-- | src/easyperform.c | 4 | ||||
-rw-r--r-- | src/pycurl.h | 13 |
3 files changed, 19 insertions, 3 deletions
@@ -137,14 +137,17 @@ util_curl_xdecref(CurlObject *self, int flags, CURL *handle) /* Decrement refcount for multi_stack. */ if (self->multi_stack != NULL) { CurlMultiObject *multi_stack = self->multi_stack; - self->multi_stack = NULL; if (multi_stack->multi_handle != NULL && handle != NULL) { /* TODO this is where we could remove the easy object from the multi object's easy_object_dict, but this requires us to have a reference to the multi object which right now we don't. */ + /* Allow threads because callbacks can be invoked */ + PYCURL_BEGIN_ALLOW_THREADS_EASY (void) curl_multi_remove_handle(multi_stack->multi_handle, handle); + PYCURL_END_ALLOW_THREADS_EASY } + self->multi_stack = NULL; Py_DECREF(multi_stack); } } diff --git a/src/easyperform.c b/src/easyperform.c index 44f21c0..5326df3 100644 --- a/src/easyperform.c +++ b/src/easyperform.c @@ -100,7 +100,7 @@ do_curl_pause(CurlObject *self, PyObject *args) #ifdef WITH_THREAD /* Save handle to current thread (used as context for python callbacks) */ saved_state = self->state; - PYCURL_BEGIN_ALLOW_THREADS + PYCURL_BEGIN_ALLOW_THREADS_EASY /* We must allow threads here because unpausing a handle can cause some of its callbacks to be invoked immediately, from inside @@ -110,7 +110,7 @@ do_curl_pause(CurlObject *self, PyObject *args) res = curl_easy_pause(self->handle, bitmask); #ifdef WITH_THREAD - PYCURL_END_ALLOW_THREADS + PYCURL_END_ALLOW_THREADS_EASY /* Restore the thread-state to whatever it was on entry */ self->state = saved_state; diff --git a/src/pycurl.h b/src/pycurl.h index 31d1eac..c123468 100644 --- a/src/pycurl.h +++ b/src/pycurl.h @@ -263,6 +263,19 @@ PYCURL_INTERNAL void pycurl_ssl_cleanup(void); # define PYCURL_END_ALLOW_THREADS \ Py_END_ALLOW_THREADS \ self->state = NULL; +# define PYCURL_BEGIN_ALLOW_THREADS_EASY \ + if (self->multi_stack == NULL) { \ + self->state = PyThreadState_Get(); \ + assert(self->state != NULL); \ + } else { \ + self->multi_stack->state = PyThreadState_Get(); \ + assert(self->multi_stack->state != NULL); \ + } \ + Py_BEGIN_ALLOW_THREADS +# define PYCURL_END_ALLOW_THREADS_EASY \ + PYCURL_END_ALLOW_THREADS \ + if (self->multi_stack != NULL) \ + self->multi_stack->state = NULL; #else # define PYCURL_DECLARE_THREAD_STATE # define PYCURL_ACQUIRE_THREAD() (1) |