static size_t ov_http_client_write_function(char *ptr, size_t size, size_t nmemb, void *userdata) { VALUE transfer; ov_http_client_io_context context; ov_http_transfer_object* transfer_ptr; /* The passed user data is the transfer: */ transfer = (VALUE) userdata; /* Get the pointer to the transfer: */ ov_http_transfer_ptr(transfer, transfer_ptr); /* Check if the operation has been cancelled, and return immediately, this will cause the perform method to return an error to the caller: */ if (transfer_ptr->cancel) { return 0; } /* Execute the write with the global interpreter lock acquired, as it needs to call Ruby methods: */ context.ptr = ptr; context.size = size; context.nmemb = nmemb; context.io = transfer_ptr->out; rb_thread_call_with_gvl(ov_http_client_write_task, &context); return context.result; }
static size_t ov_http_client_header_function(char *buffer, size_t size, size_t nitems, void *userdata) { VALUE transfer; ov_http_client_header_context context; ov_http_transfer_object* transfer_ptr; /* The passed user data is a pointer to the transfer: */ transfer = (VALUE) userdata; /* Get the pointer to the transfer: */ ov_http_transfer_ptr(transfer, transfer_ptr); /* Check if the operation has been cancelled, and return immediately, this will cause the perform method to return an error to the caller: */ if (transfer_ptr->cancel) { return 0; } /* Parse the header with the global interpreter lock acquired, as it needs to call Ruby methods: */ context.response = transfer_ptr->response; context.buffer = buffer; context.size = size; context.nitems = nitems; rb_thread_call_with_gvl(ov_http_client_header_task, &context); return context.result; }
/* * When any AsyncEngine handler runs a Ruby callback, it must * use this function, which must be called without the GVL. * TODO: Allow passing a VALUE parameter...? */ VALUE ae_take_gvl_and_run_with_error_handler(void* function) { AE_TRACE(); AE_ASSERT(AE_status != AE_STOPPED); return rb_thread_call_with_gvl(ae_run_with_error_handler, function); }
static void GLUTCALLBACK glut_WindowStatusFuncCallback0(int state) { struct callback_args *args = alloc_callback_args(); args->arg0.state = state; rb_thread_call_with_gvl((gvl_call)glut_WindowStatusFuncCallback, args); free(args); }
static void GLUTCALLBACK glut_TimerFuncCallback0(int value) { struct callback_args *args = alloc_callback_args(); args->arg0.value = value; rb_thread_call_with_gvl((gvl_call)glut_TimerFuncCallback, args); free(args); }
static void GLUTCALLBACK glut_TabletMotionFuncCallback0(int x, int y) { struct callback_args *args = alloc_callback_args(); args->arg0.x = x; args->arg1.y = y; rb_thread_call_with_gvl((gvl_call)glut_TabletMotionFuncCallback, args); free(args); }
static void GLUTCALLBACK glut_ButtonBoxFuncCallback0(int button, int state) { struct callback_args *args = alloc_callback_args(); args->arg0.button = button; args->arg1.state = state; rb_thread_call_with_gvl((gvl_call)glut_ButtonBoxFuncCallback, args); free(args); }
static void GLUTCALLBACK glut_ReshapeFuncCallback0(int width, int height) { struct callback_args *args = alloc_callback_args(); args->arg0.width = width; args->arg1.height = height; rb_thread_call_with_gvl((gvl_call)glut_ReshapeFuncCallback, args); free(args); }
static void GLUTCALLBACK glut_SpaceballRotateFuncCallback0(int x, int y, int z) { struct callback_args *args = alloc_callback_args(); args->arg0.x = x; args->arg1.y = y; args->arg2.z = z; rb_thread_call_with_gvl((gvl_call)glut_SpaceballRotateFuncCallback, args); free(args); }
static void GLUTCALLBACK glut_SpecialUpFuncCallback0(int key, int x, int y) { struct callback_args *args = alloc_callback_args(); args->arg0.key = key; args->arg1.x = x; args->arg2.y = y; rb_thread_call_with_gvl((gvl_call)glut_SpecialUpFuncCallback, args); free(args); }
static void GLUTCALLBACK glut_MenuStatusFuncCallback0(int state, int x, int y) { struct callback_args *args = alloc_callback_args(); args->arg0.state = state; args->arg1.x = x; args->arg2.y = y; rb_thread_call_with_gvl((gvl_call)glut_MenuStatusFuncCallback, args); free(args); }
static void GLUTCALLBACK glut_KeyboardFuncCallback0(unsigned char key, int x, int y) { struct callback_args *args = alloc_callback_args(); args->arg0.key = key; args->arg1.x = x; args->arg2.y = y; rb_thread_call_with_gvl((gvl_call)glut_KeyboardFuncCallback, args); free(args); }
static void grpc_rb_call_credentials_plugin_get_metadata( void *state, grpc_auth_metadata_context context, grpc_credentials_plugin_metadata_cb cb, void *user_data) { callback_params params; params.get_metadata = (VALUE)state; params.context = context; params.user_data = user_data; params.callback = cb; rb_thread_call_with_gvl(grpc_rb_call_credentials_callback_with_gil, (void*)(¶ms)); }
static void GLUTCALLBACK glut_JoystickFuncCallback0(unsigned int button_mask, int x, int y, int z) { struct callback_args *args = alloc_callback_args(); args->arg0.button_mask = button_mask; args->arg1.x = x; args->arg2.y = y; args->arg3.z = z; rb_thread_call_with_gvl((gvl_call)glut_JoystickFuncCallback, args); free(args); }
static void GLUTCALLBACK glut_TabletButtonFuncCallback0(int button, int state, int x, int y) { struct callback_args *args = alloc_callback_args(); args->arg0.button = button; args->arg1.state = state; args->arg2.x = x; args->arg3.y = y; rb_thread_call_with_gvl((gvl_call)glut_TabletButtonFuncCallback, args); free(args); }
static void callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data) { struct gvl_callback cb; cb.closure = (Closure *) user_data; cb.retval = retval; cb.parameters = parameters; cb.done = false; if (rbffi_thread_has_gvl_p()) { callback_with_gvl(&cb); #if defined(HAVE_RUBY_NATIVE_THREAD_P) && defined (HAVE_RB_THREAD_CALL_WITH_GVL) } else if (ruby_native_thread_p()) { rb_thread_call_with_gvl(callback_with_gvl, &cb); #endif #if defined(DEFER_ASYNC_CALLBACK) && !defined(_WIN32) } else { bool empty = false; pthread_mutex_init(&cb.async_mutex, NULL); pthread_cond_init(&cb.async_cond, NULL); // Now signal the async callback thread pthread_mutex_lock(&async_cb_mutex); empty = async_cb_list == NULL; cb.next = async_cb_list; async_cb_list = &cb; pthread_mutex_unlock(&async_cb_mutex); #if !defined(HAVE_RB_THREAD_BLOCKING_REGION) // Only signal if the list was empty if (empty) { char c; write(async_cb_pipe[1], &c, 1); } #else pthread_cond_signal(&async_cb_cond); #endif // Wait for the thread executing the ruby callback to signal it is done pthread_mutex_lock(&cb.async_mutex); while (!cb.done) { pthread_cond_wait(&cb.async_cond, &cb.async_mutex); } pthread_mutex_unlock(&cb.async_mutex); pthread_cond_destroy(&cb.async_cond); pthread_mutex_destroy(&cb.async_mutex); #elif defined(DEFER_ASYNC_CALLBACK) && defined(_WIN32) } else {
static int ov_http_client_debug_function(CURL* handle, curl_infotype type, char* data, size_t size, void* userptr) { VALUE transfer; ov_http_client_debug_context context; ov_http_transfer_object* transfer_ptr; /* The passed user pointer is the transfer: */ transfer = (VALUE) userptr; /* 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: */ 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); return 0; }
/* * Callback for the 'ping' command. */ static void rbverse_cb_ping( void *unused, const char *addr, const char *msg ) { const char *(args[2]) = { addr, msg }; rb_thread_call_with_gvl( rbverse_cb_ping_body, args ); }
static void* ov_http_client_wait_task(void* data) { CURLMsg* message; int count; int pending; long timeout; ov_http_client_wait_context* context_ptr; #if LIBCURL_VERSION_NUM < 0x071c00 fd_set fd_read; fd_set fd_write; fd_set fd_error; int fd_count; struct timeval tv; #endif /* The passed data is the wait context: */ context_ptr = data; /* Get the timeout preferred by libcurl, or one 100 ms by default: */ curl_multi_timeout(context_ptr->handle, &timeout); if (timeout < 0) { timeout = 100; } #if LIBCURL_VERSION_NUM >= 0x071c00 /* Wait till there is activity: */ context_ptr->code = curl_multi_wait(context_ptr->handle, NULL, 0, timeout, NULL); if (context_ptr->code != CURLE_OK) { return NULL; } #else /* Versions of libcurl older than 7.28.0 don't provide the 'curl_multi_wait' function, so we need to get the file descriptors used by libcurl, and explicitly use the 'select' system call: */ FD_ZERO(&fd_read); FD_ZERO(&fd_write); FD_ZERO(&fd_error); context_ptr->code = curl_multi_fdset(context_ptr->handle, &fd_read, &fd_write, &fd_error, &fd_count); if (context_ptr->code != CURLE_OK) { return NULL; } tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; select(fd_count + 1, &fd_read, &fd_write, &fd_error, &tv); #endif /* Let libcurl do its work, even if no file descriptor needs attention. This is necessary because some of its activities can't be monitored using file descriptors. */ context_ptr->code = curl_multi_perform(context_ptr->handle, &pending); if (context_ptr->code != CURLE_OK) { return NULL; } /* Check if there are finished transfers. For each of them call the function that completes them, with the global interpreter lock acquired, as it will call Ruby code. */ while ((message = curl_multi_info_read(context_ptr->handle, &count)) != NULL) { if (message->msg == CURLMSG_DONE) { /* Call the Ruby code that completes the transfer: */ rb_thread_call_with_gvl(ov_http_client_complete_task, message); /* Remove the easy handle from the multi handle and discard it: */ curl_multi_remove_handle(context_ptr->handle, message->easy_handle); curl_easy_cleanup(message->easy_handle); } } /* Everything worked correctly: */ context_ptr->code = CURLE_OK; return NULL; }
static void GLUTCALLBACK glut_IdleFuncCallback0(void) { rb_thread_call_with_gvl((gvl_call)glut_IdleFuncCallback, NULL); }
static void GLUTCALLBACK glut_DisplayFuncCallback0(void) { rb_thread_call_with_gvl(glut_DisplayFuncCallback, NULL); }
static void tick_callback() { if (__sync_fetch_and_add(&callback_enabled, 0)) { rb_thread_call_with_gvl((void *(*)(void *))&tick_callback_impl, NULL); } }
static void GLUTCALLBACK glut_OverlayDisplayFuncCallback0(void) { rb_thread_call_with_gvl((gvl_call)glut_OverlayDisplayFuncCallback, NULL); }