mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* thread.c (rb_thread_blocking_region): add a comment.
* thread.c (rb_thread_call_without_gvl): added as a alias of rb_thread_blocking_region(). * thread.c (rb_thread_call_with_gvl): added. * vm_core.h (rb_thread_t#blocking_region_buffer): added for rb_thread_call_with_gvl(). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@21185 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
f396a10e13
commit
9c04a0647f
3 changed files with 85 additions and 1 deletions
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
|||
Tue Dec 30 16:56:09 2008 Koichi Sasada <ko1@atdot.net>
|
||||
|
||||
* thread.c (rb_thread_blocking_region): add a comment.
|
||||
|
||||
* thread.c (rb_thread_call_without_gvl): added as a alias of
|
||||
rb_thread_blocking_region().
|
||||
|
||||
* thread.c (rb_thread_call_with_gvl): added.
|
||||
|
||||
* vm_core.h (rb_thread_t#blocking_region_buffer): added for
|
||||
rb_thread_call_with_gvl().
|
||||
|
||||
Mon Dec 29 23:41:42 2008 Koichi Sasada <ko1@atdot.net>
|
||||
|
||||
* ext/dl/test/test_base.rb: add libc search logic.
|
||||
|
|
73
thread.c
73
thread.c
|
@ -1014,9 +1014,14 @@ rb_thread_blocking_region_end(struct rb_blocking_region_buffer *region)
|
|||
*
|
||||
* NOTE: You can not execute most of Ruby C API and touch Ruby objects
|
||||
* in `func()' and `ubf()' because current thread doesn't acquire
|
||||
* GVL (cause synchronization problem). If you need to do it,
|
||||
* GVL (cause synchronization problem). Especially, ALLOC*() are
|
||||
* forbidden because they are related to GC. If you need to do it,
|
||||
* read source code of C APIs and confirm by yourself.
|
||||
*
|
||||
* NOTE: In short, this API is difficult to use safely. I recommend you
|
||||
* use other ways if you have. We lack experiences to use this API.
|
||||
* Please report your problem related on it.
|
||||
*
|
||||
* Safe C API:
|
||||
* * rb_thread_interrupted() - check interrupt flag
|
||||
*/
|
||||
|
@ -1040,6 +1045,72 @@ rb_thread_blocking_region(
|
|||
return val;
|
||||
}
|
||||
|
||||
/* alias of rb_thread_blocking_region() */
|
||||
|
||||
VALUE
|
||||
rb_thread_call_without_gvl(
|
||||
rb_blocking_function_t *func, void *data1,
|
||||
rb_unblock_function_t *ubf, void *data2)
|
||||
{
|
||||
return rb_thread_blocking_region(func, data1, ubf, data2);
|
||||
}
|
||||
|
||||
/*
|
||||
* rb_thread_call_with_gvl - re-enter into Ruby world while releasing GVL.
|
||||
*
|
||||
* While releasing GVL using rb_thread_blocking_region() or
|
||||
* rb_thread_call_without_gvl(), you can not access Ruby values or invoke methods.
|
||||
* If you need to access it, you must use this function rb_thread_call_with_gvl().
|
||||
*
|
||||
* This function rb_thread_call_with_gvl() does:
|
||||
* (1) acquire GVL.
|
||||
* (2) call passed function `func'.
|
||||
* (3) release GVL.
|
||||
* (4) return a value which is returned at (2).
|
||||
*
|
||||
* NOTE: You should not return Ruby object at (2) because such Object
|
||||
* will not marked.
|
||||
*
|
||||
* NOTE: If an exception is raised in `func', this function "DOES NOT"
|
||||
* protect (catch) the exception. If you have any resources
|
||||
* which should free before throwing exception, you need use
|
||||
* rb_protect() in `func' and return a value which represents
|
||||
* exception is raised.
|
||||
*
|
||||
* NOTE: This functions should not be called by a thread which
|
||||
* is not created as Ruby thread (created by Thread.new or so).
|
||||
* In other words, this function *DOES NOT* associate
|
||||
* NON-Ruby thread to Ruby thread.
|
||||
*/
|
||||
void *
|
||||
rb_thread_call_with_gvl(void *(*func)(void *), void *data1)
|
||||
{
|
||||
rb_thread_t *th = ruby_thread_from_native();
|
||||
struct rb_blocking_region_buffer *brb;
|
||||
struct rb_unblock_callback prev_unblock;
|
||||
void *r;
|
||||
|
||||
if (th == 0) {
|
||||
/* Error is occurred, but we can't use rb_bug()
|
||||
* because this thread is not Ruby's thread.
|
||||
* What should we do?
|
||||
*/
|
||||
|
||||
fprintf(stderr, "[BUG] rb_thread_call_with_gvl() is called by non-ruby thread\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
brb = (struct rb_blocking_region_buffer *)th->blocking_region_buffer;
|
||||
prev_unblock = th->unblock;
|
||||
|
||||
blocking_region_end(th, brb);
|
||||
/* enter to Ruby world: You can access Ruby values, methods and so on. */
|
||||
r = (*func)(data1);
|
||||
/* levae from Ruby world: You can not access Ruby values, etc. */
|
||||
blocking_region_begin(th, brb, prev_unblock.func, prev_unblock.arg);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* Thread.pass => nil
|
||||
|
|
|
@ -363,6 +363,7 @@ typedef struct rb_thread_struct
|
|||
int slice;
|
||||
|
||||
native_thread_data_t native_thread_data;
|
||||
void *blocking_region_buffer;
|
||||
|
||||
VALUE thgroup;
|
||||
VALUE value;
|
||||
|
|
Loading…
Add table
Reference in a new issue