summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2020-12-24 04:18:17 +0900
committerKoichi Sasada <ko1@atdot.net>2020-12-24 04:30:49 +0900
commit7fcb6b3dbe7517fe5426fdb6871cd4940a71b7e8 (patch)
treec4d4fff4b44b0cca9504f1cfbcbfaeed7d81c193
parent458d5175b9f3476c4d0c95c35458aab10c78e647 (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.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/ractor.c b/ractor.c
index 585435c820..26322f5099 100644
--- a/ractor.c
+++ b/ractor.c
@@ -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;
}