diff options
author | nagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-07-30 15:52:15 +0000 |
---|---|---|
committer | nagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-07-30 15:52:15 +0000 |
commit | cd1f00780b2a412dcb01fcd5abd46df3a547e788 (patch) | |
tree | 4209039f3fab9b6bb73a652dac3b433006479b34 /thread.c | |
parent | 3eb0620c2a901b12e6fb752fd1ae668ed8f2b918 (diff) |
merge revision(s) r46419,r46429: [Backport #9940]
* 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.
* thread.c: added
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_1@47009 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'thread.c')
-rw-r--r-- | thread.c | 58 |
1 files changed, 42 insertions, 16 deletions
@@ -2746,22 +2746,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 @@ -2830,26 +2833,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: @@ -4778,6 +4790,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. |