diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-10-30 01:55:38 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-10-30 01:55:38 +0000 |
commit | 411b74709163708d46843970e6acdde85de4ae14 (patch) | |
tree | d971d2e4038cb8066cb306c32e52c43f5cf70dad /thread.c | |
parent | 22bd95ded46f7163bde16e4782648de2ce5e87a1 (diff) |
* thread.c (rb_thread_blocking_region): must ensure to unlock GVL.
[ruby-dev:39579]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@25566 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'thread.c')
-rw-r--r-- | thread.c | 30 |
1 files changed, 29 insertions, 1 deletions
@@ -1028,6 +1028,23 @@ rb_thread_blocking_region_end(struct rb_blocking_region_buffer *region) RUBY_VM_CHECK_INTS(); } +#ifndef PROHIBIT_FUNCTION_CAST +#define PROHIBIT_FUNCTION_CAST 0 +#endif +#if PROHIBIT_FUNCTION_CAST +struct blocking_function_args { + rb_blocking_function_t *func; + void *data; +}; + +static VALUE +call_blocking_function(VALUE arg) +{ + struct blocking_function_args *blocking = (void *)arg; + return (blocking->func)(blocking->data); +} +#endif + /* * rb_thread_blocking_region - permit concurrent/parallel execution. * @@ -1070,6 +1087,10 @@ rb_thread_blocking_region( { VALUE val; rb_thread_t *th = GET_THREAD(); + int status; +#if PROHIBIT_FUNCTION_CAST + struct blocking_function_args args; +#endif if (ubf == RUBY_UBF_IO || ubf == RUBY_UBF_PROCESS) { ubf = ubf_select; @@ -1077,8 +1098,15 @@ rb_thread_blocking_region( } BLOCKING_REGION({ - val = func(data1); +#if PROHIBIT_FUNCTION_CAST + args.func = func; + args.data = data1; + val = rb_protect(call_blocking_function, (VALUE)&args, &status); +#else + val = rb_protect((VALUE (*)(VALUE))func, (VALUE)data1, &status); +#endif }, ubf, data2); + if (status) rb_jump_tag(status); return val; } |