diff options
author | Koichi Sasada <ko1@atdot.net> | 2020-12-24 04:18:17 +0900 |
---|---|---|
committer | Koichi Sasada <ko1@atdot.net> | 2020-12-24 04:30:49 +0900 |
commit | 7fcb6b3dbe7517fe5426fdb6871cd4940a71b7e8 (patch) | |
tree | c4d4fff4b44b0cca9504f1cfbcbfaeed7d81c193 | |
parent | 458d5175b9f3476c4d0c95c35458aab10c78e647 (diff) |
fix ractor-locking around rb_ractor_thread_list()
With locking a ractor, rb_ary_push() can call RB_VM_LOCK_ENTER()
and it violates an assertion: should not acquire ractor-lock.
-rw-r--r-- | ractor.c | 30 |
1 files changed, 21 insertions, 9 deletions
@@ -1672,21 +1672,33 @@ rb_ractor_living_thread_num(const rb_ractor_t *r) VALUE rb_ractor_thread_list(rb_ractor_t *r) { - VALUE ary = rb_ary_new(); rb_thread_t *th = 0; + VALUE *ts; + int ts_cnt; RACTOR_LOCK(r); - list_for_each(&r->threads.set, th, lt_node) { - switch (th->status) { - case THREAD_RUNNABLE: - case THREAD_STOPPED: - case THREAD_STOPPED_FOREVER: - rb_ary_push(ary, th->self); - default: - break; + { + ts = ALLOCA_N(VALUE, r->threads.cnt); + ts_cnt = 0; + + list_for_each(&r->threads.set, th, lt_node) { + switch (th->status) { + case THREAD_RUNNABLE: + case THREAD_STOPPED: + case THREAD_STOPPED_FOREVER: + ts[ts_cnt++] = th->self; + default: + break; + } } } RACTOR_UNLOCK(r); + + VALUE ary = rb_ary_new(); + for (int i=0; i<ts_cnt; i++) { + rb_ary_push(ary, ts[i]); + } + return ary; } |