diff --git a/sdk/ext/ovirtsdk4c/ov_http_client.c b/sdk/ext/ovirtsdk4c/ov_http_client.c index abc4d10..2e50fd0 100644 --- a/sdk/ext/ovirtsdk4c/ov_http_client.c +++ b/sdk/ext/ovirtsdk4c/ov_http_client.c @@ -34,6 +34,9 @@ limitations under the License. #include "ov_http_response.h" #include "ov_http_transfer.h" +/* thread.c (export) */ +extern int ruby_thread_has_gvl_p(void); + /* Class: */ VALUE ov_http_client_class; @@ -490,12 +493,20 @@ static int ov_http_client_debug_function(CURL* handle, curl_infotype type, char* /* Get the pointer to the transfer: */ ov_http_transfer_ptr(transfer, transfer_ptr); - /* Execute the debug code with the global interpreter lock acquired, as it needs to call Ruby methods: */ + /* The global interpreter lock may be acquired or not, so we need to check and either call the task directly + or else call it after acquiring the lock. Note that the `ruby_thread_has_gvl_p` function that we use to + check if the GVL is acquired is marked as experimental, and not defined in `thread.h`, so it may be + removed at any time, but I didn't find any other way to check if the GVL is acquired. */ context.client = transfer_ptr->client; context.type = type; context.data = data; context.size = size; - rb_thread_call_with_gvl(ov_http_client_debug_task, &context); + if (ruby_thread_has_gvl_p()) { + ov_http_client_debug_task(&context); + } + else { + rb_thread_call_with_gvl(ov_http_client_debug_task, &context); + } return 0; } @@ -998,7 +1009,7 @@ static void ov_http_client_prepare_handle(ov_http_client_object* client_ptr, ov_ /* Set the headers: */ if (!NIL_P(request_ptr->headers)) { - rb_hash_foreach(request_ptr->headers, ov_http_client_add_header, (VALUE) headers); + rb_hash_foreach(request_ptr->headers, (int (*)(VALUE, VALUE, VALUE)) ov_http_client_add_header, (VALUE) headers); } curl_easy_setopt(handle, CURLOPT_HTTPHEADER, *headers);