Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
/*
 * 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);
}
Пример #4
0
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);
}
Пример #5
0
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);
}
Пример #6
0
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);
}
Пример #7
0
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);
}
Пример #8
0
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);
}
Пример #9
0
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);
}
Пример #10
0
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);
}
Пример #11
0
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);
}
Пример #12
0
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);
}
Пример #13
0
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*)(&params));
}
Пример #14
0
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);
}
Пример #15
0
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);
}
Пример #16
0
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 {
Пример #17
0
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;
}
Пример #18
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 );
}
Пример #19
0
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;
}
Пример #20
0
static void GLUTCALLBACK
glut_IdleFuncCallback0(void) {
  rb_thread_call_with_gvl((gvl_call)glut_IdleFuncCallback, NULL);
}
Пример #21
0
static void GLUTCALLBACK
glut_DisplayFuncCallback0(void) {
  rb_thread_call_with_gvl(glut_DisplayFuncCallback, NULL);
}
Пример #22
0
static void tick_callback() {
    if (__sync_fetch_and_add(&callback_enabled, 0)) {
        rb_thread_call_with_gvl((void *(*)(void *))&tick_callback_impl, NULL);
    }
}
Пример #23
0
static void GLUTCALLBACK
glut_OverlayDisplayFuncCallback0(void) {
  rb_thread_call_with_gvl((gvl_call)glut_OverlayDisplayFuncCallback, NULL);
}