diff options
author | Max Romanov <max.romanov@nginx.com> | 2020-12-07 18:17:25 +0000 |
---|---|---|
committer | Max Romanov <max.romanov@nginx.com> | 2020-12-07 18:17:25 +0000 |
commit | d3796d1fb7008629a8fa505481dab96efe60cbdb (patch) | |
tree | c299ebcd54447fb280659374d07121db3d064850 /src/ruby/nxt_ruby.c | |
parent | c7bd96b4769abb11a92a081061bc83171d5ed6ac (diff) | |
download | unit-d3796d1fb7008629a8fa505481dab96efe60cbdb.tar.gz unit-d3796d1fb7008629a8fa505481dab96efe60cbdb.tar.bz2 |
Ruby: fixed crash on thread start.
Ruby threads need to be created with GVL; otherwise, an attempt to access
locked resources may occur, causing a crash.
The issue was occasionally reproduced on Ubuntu 18.04 with Ruby 2.5.1
while running test_ruby_application_threads.
Diffstat (limited to '')
-rw-r--r-- | src/ruby/nxt_ruby.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/src/ruby/nxt_ruby.c b/src/ruby/nxt_ruby.c index 698d4a43..0aad887d 100644 --- a/src/ruby/nxt_ruby.c +++ b/src/ruby/nxt_ruby.c @@ -38,6 +38,7 @@ static int nxt_ruby_init_io(nxt_ruby_ctx_t *rctx); static void nxt_ruby_request_handler(nxt_unit_request_info_t *req); static void *nxt_ruby_request_handler_gvl(void *req); static int nxt_ruby_ready_handler(nxt_unit_ctx_t *ctx); +static void *nxt_ruby_thread_create_gvl(void *rctx); static VALUE nxt_ruby_thread_func(VALUE arg); static void *nxt_ruby_unit_run(void *ctx); static void nxt_ruby_ubf(void *ctx); @@ -1141,7 +1142,7 @@ nxt_ruby_ready_handler(nxt_unit_ctx_t *ctx) rctx->ctx = ctx; - res = rb_thread_create(RUBY_METHOD_FUNC(nxt_ruby_thread_func), rctx); + res = (VALUE) rb_thread_call_with_gvl(nxt_ruby_thread_create_gvl, rctx); if (nxt_fast_path(res != Qnil)) { nxt_unit_debug(ctx, "thread #%d created", (int) (i + 1)); @@ -1159,6 +1160,17 @@ nxt_ruby_ready_handler(nxt_unit_ctx_t *ctx) } +static void * +nxt_ruby_thread_create_gvl(void *rctx) +{ + VALUE res; + + res = rb_thread_create(RUBY_METHOD_FUNC(nxt_ruby_thread_func), rctx); + + return (void *) (uintptr_t) res; +} + + static VALUE nxt_ruby_thread_func(VALUE arg) { |