Project

General

Profile

Actions

Feature #4328

closed

export rb_thread_call_with_gvl()

Added by normalperson (Eric Wong) almost 14 years ago. Updated about 12 years ago.

Status:
Closed
Target version:
[ruby-core:34888]

Description

=begin
I think it is general enough to remain supported along
with the rest of the MRI C API, especially since
rb_thread_blocking_region() exists and is supported.

It's useful for interacting with certain C libraries that expect a
user-supplied callback function so the extension can allocate a Ruby
object inside the callback.

It can also be easily made a no-op for Ruby implementations without a
GVL.
=end


Files

0001-export-rb_thread_call_with_gvl.patch (1.5 KB) 0001-export-rb_thread_call_with_gvl.patch [PATCH] export rb_thread_call_with_gvl() normalperson (Eric Wong), 01/27/2011 03:51 PM

Related issues 1 (0 open1 closed)

Related to Ruby master - Feature #5543: rb_thread_blocking_region() API is poorly designedClosedko1 (Koichi Sasada)11/02/2011Actions
Actions #1

Updated by usa (Usaku NAKAMURA) almost 14 years ago

  • Status changed from Open to Assigned
  • Assignee set to ko1 (Koichi Sasada)

=begin

=end

Updated by normalperson (Eric Wong) over 13 years ago

I should note that even Rubinius has this function in it's C API.

Updated by ko1 (Koichi Sasada) over 13 years ago

Hi,

As you can read in comment, this API is difficult to use. There are
some assumptions for caller. I'm not sure that these assumptions are
reasonable or not. This is why we don't put into public API.

BTW, the naming "_with_gvl" is reasonable for native English speakers?

(2011/01/27 15:51), Eric Wong wrote:

Feature #4328: export rb_thread_call_with_gvl()
http://redmine.ruby-lang.org/issues/show/4328

Author: Eric Wong
Status: Open, Priority: Normal
Category: core, Target version: 1.9.3

I think it is general enough to remain supported along
with the rest of the MRI C API, especially since
rb_thread_blocking_region() exists and is supported.

It's useful for interacting with certain C libraries that expect a
user-supplied callback function so the extension can allocate a Ruby
object inside the callback.

It can also be easily made a no-op for Ruby implementations without a
GVL.


http://redmine.ruby-lang.org

--
// SASADA Koichi at atdot dot net

Updated by normalperson (Eric Wong) over 13 years ago

SASADA Koichi wrote:

Hi,

As you can read in comment, this API is difficult to use. There are
some assumptions for caller. I'm not sure that these assumptions are
reasonable or not. This is why we don't put into public API.

I think the assumptions and requirements for calling this function are
reasonable (and best of all, well-documented). The API isn't difficult
to me and the documentation is clear as to what is safe and what is not.

Threading APIs can always be tricky, but I think the C API for GVL is
a good one.

BTW, the naming "_with_gvl" is reasonable for native English speakers?

Yes.

Thank you for the response.

--
Eric Wong

Updated by ko1 (Koichi Sasada) over 13 years ago

Hi,

(2011/06/14 14:56), Eric Wong wrote:

I think the assumptions and requirements for calling this function are
reasonable (and best of all, well-documented). The API isn't difficult
to me and the documentation is clear as to what is safe and what is not.

Threading APIs can always be tricky, but I think the C API for GVL is
a good one.

I think a requirement "caller should be a Ruby thread" is difficult.

For example, external library calls registered callback in other native
threads (not ruby threads). If C extension programmer does not know
such specification of external library, (s)he would make and register a
callback function using this API. Finally, the Ruby code run on non
Ruby code. I'm afraid of such situation.

To avoid this situation, one solution is checking "the thread is really
Ruby thread or not" when rb_thread_call_with_gvl() is called. This
check was already introduced into this API.

Other solution is making the non-ruby thread to ruby thread. I feel
necessity of such API, however, I need more consideration to implement it.

To limit to usage of rb_thread_call_with_gvl() as "only blocking
function", former (current) solution is enough.

BTW, the naming "_with_gvl" is reasonable for native English speakers?

Yes.

Thank you. We keep this name.

Please discuss with me about naming of another "_with_gvl".
In gc.c, there are other "_with_gvl" functions.

  • negative_size_allocation_error_with_gvl
  • gc_with_gvl

The functions are callback of rb_thread_call_with_gvl().

The meaning of "with_gvl" in rb_thread_call_with_gvl() is "acquire GVL
and call passed function". However, above two functions use then name
"*_with_gvl" in different meaning (run in GVL acquired situation, only).

Do you have good naming idea for them?

--
// SASADA Koichi at atdot dot net

Updated by normalperson (Eric Wong) over 13 years ago

SASADA Koichi wrote:

Hi,

(2011/06/14 14:56), Eric Wong wrote:

I think the assumptions and requirements for calling this function are
reasonable (and best of all, well-documented). The API isn't difficult
to me and the documentation is clear as to what is safe and what is not.

Threading APIs can always be tricky, but I think the C API for GVL is
a good one.

I think a requirement "caller should be a Ruby thread" is difficult.

For example, external library calls registered callback in other native
threads (not ruby threads). If C extension programmer does not know
such specification of external library, (s)he would make and register a
callback function using this API. Finally, the Ruby code run on non
Ruby code. I'm afraid of such situation.

To avoid this situation, one solution is checking "the thread is really
Ruby thread or not" when rb_thread_call_with_gvl() is called. This
check was already introduced into this API.

Yup, I like this check. Most C libraries I've used with do not start
threads internally, so I don't think it's a big problem. I always
review code to all libraries I use so I don't hit surprises like this,
though many programmers do not.

Other solution is making the non-ruby thread to ruby thread. I feel
necessity of such API, however, I need more consideration to implement it.

This would be interesting, I look forward to it.

To limit to usage of rb_thread_call_with_gvl() as "only blocking
function", former (current) solution is enough.

Yes, I strongly believe rb_thread_call_with_gvl() is useful for many
general cases already.

BTW, the naming "_with_gvl" is reasonable for native English speakers?

Yes.

Thank you. We keep this name.

Please discuss with me about naming of another "_with_gvl".
In gc.c, there are other "_with_gvl" functions.

  • negative_size_allocation_error_with_gvl
  • gc_with_gvl

The functions are callback of rb_thread_call_with_gvl().

The meaning of "with_gvl" in rb_thread_call_with_gvl() is "acquire GVL
and call passed function". However, above two functions use then name
"*_with_gvl" in different meaning (run in GVL acquired situation, only).

I agree, "*_with_gvl" having two meanings is confusing.

Do you have good naming idea for them?

Not sure, maybe "*_in_gvl"?

Or "ingvl_*" as prefix since io.c already uses "maygvl_" and "nogvl_" as
prefixes.

Maybe we should avoid "gvl" in the name completely for these two
functions. Most Ruby functions need GVL anyways and they don't have
"gvl" in the name.

--
Eric Wong

Updated by drbrain (Eric Hodel) over 13 years ago

On Jun 14, 2011, at 2:44 AM, Eric Wong wrote:

SASADA Koichi wrote:

The meaning of "with_gvl" in rb_thread_call_with_gvl() is "acquire GVL
and call passed function". However, above two functions use then name
"*_with_gvl" in different meaning (run in GVL acquired situation, only).

I agree, "*_with_gvl" having two meanings is confusing.

Do you have good naming idea for them?

Not sure, maybe "*_in_gvl"?

"*_if_gvl"?

Or "ingvl_*" as prefix since io.c already uses "maygvl_" and "nogvl_" as
prefixes.

Maybe we should avoid "gvl" in the name completely for these two
functions. Most Ruby functions need GVL anyways and they don't have
"gvl" in the name.

Actions #8

Updated by ko1 (Koichi Sasada) over 13 years ago

  • Status changed from Assigned to Closed
  • % Done changed from 0 to 100

This issue was solved with changeset r32486.
Eric, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


  • internal.h (rb_thread_call_with_gvl, rb_thread_call_without_gvl):
    make them visible as experimental C APIs. fixes Feature #4328.

Updated by drbrain (Eric Hodel) over 12 years ago

  • Description updated (diff)

I was going to use rb_thread_call_with_gvl for #6612, but the declaration was moved to internal.h which is not exported and causes a warning when compiling zlib.c. Was this intentional? The current location seems to allow use by core ruby only.

To be usable by extensions the declaration should be in include/ruby/intern.h alongside rb_thread_blocking_region.

Updated by drbrain (Eric Hodel) over 12 years ago

  • Status changed from Closed to Assigned

Updated by ko1 (Koichi Sasada) about 12 years ago

  • Status changed from Assigned to Closed

Now we have include/ruby/thread.h: void *rb_thread_call_with_gvl(void *(*func)(void *), void *data1);

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0