summaryrefslogtreecommitdiffhomepage
path: root/src/ruby
diff options
context:
space:
mode:
authorMax Romanov <max.romanov@nginx.com>2020-12-07 18:17:25 +0000
committerMax Romanov <max.romanov@nginx.com>2020-12-07 18:17:25 +0000
commitd3796d1fb7008629a8fa505481dab96efe60cbdb (patch)
treec299ebcd54447fb280659374d07121db3d064850 /src/ruby
parentc7bd96b4769abb11a92a081061bc83171d5ed6ac (diff)
downloadunit-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 'src/ruby')
-rw-r--r--src/ruby/nxt_ruby.c14
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)
{