summaryrefslogtreecommitdiff
path: root/thread.c
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-12-20 09:41:30 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-12-20 09:41:30 +0000
commit449bf5f93d25690ca282e35d2898be3789058f7e (patch)
treed757c574e11732d21b823a0f458be3f2b7ac0fd2 /thread.c
parentd92d9a2661d62faf4a95a400109fd0c9f0ece256 (diff)
[Backport #7538]
* thread.c (exec_event_hooks): exceptions in event hooks should not propagate outside. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_3@38504 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'thread.c')
-rw-r--r--thread.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/thread.c b/thread.c
index eb0be9f1d0..710035d828 100644
--- a/thread.c
+++ b/thread.c
@@ -4138,16 +4138,25 @@ set_threads_event_flags(int flag)
static inline int
exec_event_hooks(const rb_event_hook_t *hook, rb_event_flag_t flag, VALUE self, ID id, VALUE klass)
{
- int removed = 0;
+ volatile int removed = 0;
+ const rb_event_hook_t *volatile hnext = 0;
+ int state;
+
+ PUSH_TAG();
+ if ((state = EXEC_TAG()) != 0) {
+ hook = hnext;
+ }
for (; hook; hook = hook->next) {
if (hook->flag & RUBY_EVENT_REMOVED) {
removed++;
continue;
}
if (flag & hook->flag) {
+ hnext = hook->next;
(*hook->func)(flag, hook->data, self, id, klass);
}
}
+ POP_TAG();
return removed;
}