diff options
author | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-06-13 08:50:11 +0000 |
---|---|---|
committer | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-06-13 08:50:11 +0000 |
commit | ddae6a05d7442f25ac04eb3338ffa8a8b4895d3f (patch) | |
tree | 5a69624215e1a163a8ff7bcc583aa43edcdb1b60 /thread.c | |
parent | 537b4a64227aebf357a5c3f570e01be5f2f824fd (diff) | |
download | ruby-ddae6a05d7442f25ac04eb3338ffa8a8b4895d3f.tar.gz |
* vm_trace.c: clear and restore recursive checking thread local data
to avoid unexpected throw from TracePoint.
[Bug #9940]
* test/ruby/test_settracefunc.rb: add a test.
* thread.c: adde
* rb_threadptr_reset_recursive_data(rb_thread_t *th);
* rb_threadptr_restore_recursive_data(rb_thread_t *th, VALUE old);
* vm_core.h: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46419 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'thread.c')
-rw-r--r-- | thread.c | 58 |
1 files changed, 42 insertions, 16 deletions
@@ -2738,22 +2738,25 @@ rb_thread_inspect(VALUE thread) return str; } -VALUE -rb_thread_local_aref(VALUE thread, ID id) +static VALUE +threadptr_local_aref(rb_thread_t *th, ID id) { - rb_thread_t *th; st_data_t val; - GetThreadPtr(thread, th); - if (!th->local_storage) { - return Qnil; - } - if (st_lookup(th->local_storage, id, &val)) { + if (th->local_storage && st_lookup(th->local_storage, id, &val)) { return (VALUE)val; } return Qnil; } +VALUE +rb_thread_local_aref(VALUE thread, ID id) +{ + rb_thread_t *th; + GetThreadPtr(thread, th); + return threadptr_local_aref(th, id); +} + /* * call-seq: * thr[sym] -> obj or nil @@ -2822,26 +2825,35 @@ rb_thread_aref(VALUE thread, VALUE key) return rb_thread_local_aref(thread, id); } -VALUE -rb_thread_local_aset(VALUE thread, ID id, VALUE val) +static VALUE +threadptr_local_aset(rb_thread_t *th, ID id, VALUE val) { - rb_thread_t *th; - GetThreadPtr(thread, th); - - if (OBJ_FROZEN(thread)) { - rb_error_frozen("thread locals"); - } if (NIL_P(val)) { if (!th->local_storage) return Qnil; st_delete_wrap(th->local_storage, id); return Qnil; } + else { if (!th->local_storage) { th->local_storage = st_init_numtable(); } st_insert(th->local_storage, id, val); return val; } +} + +VALUE +rb_thread_local_aset(VALUE thread, ID id, VALUE val) +{ + rb_thread_t *th; + GetThreadPtr(thread, th); + + if (OBJ_FROZEN(thread)) { + rb_error_frozen("thread locals"); + } + + return threadptr_local_aset(th, id, val); +} /* * call-seq: @@ -4674,6 +4686,20 @@ recursive_list_access(void) return list; } +VALUE +rb_threadptr_reset_recursive_data(rb_thread_t *th) +{ + VALUE old = threadptr_local_aref(th, recursive_key); + threadptr_local_aset(th, recursive_key, Qnil); + return old; +} + +void +rb_threadptr_restore_recursive_data(rb_thread_t *th, VALUE old) +{ + threadptr_local_aset(th, recursive_key, old); +} + /* * Returns Qtrue iff obj_id (or the pair <obj, paired_obj>) is already * in the recursion list. |