diff options
Diffstat (limited to 'event.cpp')
-rw-r--r-- | event.cpp | 82 |
1 files changed, 37 insertions, 45 deletions
@@ -58,7 +58,7 @@ signal_list_t; active, which is the one that new events is written to. The inactive one contains the events that are currently beeing performed. */ -static signal_list_t sig_list[]= {{0,0},{0,0}}; +static signal_list_t sig_list[2]= {{},{}}; /** The index of sig_list that is the list of signals currently written to @@ -69,9 +69,8 @@ typedef std::vector<event_t *> event_list_t; /** List of event handlers. - Note this is inspected by our signal handler, so we must block signals around manipulating it. */ -static event_list_t events; +static event_list_t s_event_handlers; /** List of event handlers that should be removed */ @@ -82,6 +81,17 @@ static event_list_t killme; */ static event_list_t blocked; +/** Variables (one per signal) set when a signal is observed. This is inspected by a signal handler. */ +static volatile bool s_observed_signals[NSIG] = {}; +static void set_signal_observed(int sig, bool val) +{ + ASSERT_IS_MAIN_THREAD(); + if (sig >= 0 && (size_t)sig < sizeof s_observed_signals / sizeof *s_observed_signals) + { + s_observed_signals[sig] = val; + } +} + /** Tests if one event instance matches the definition of a event class. If both the class and the instance name a function, @@ -144,12 +154,15 @@ static int event_match(const event_t &classv, const event_t &instance) */ static int event_is_blocked(const event_t &e) { - block_t *block; + const block_t *block; parser_t &parser = parser_t::principal_parser(); - for (block = parser.current_block; block; block = block->outer) + + size_t idx = 0; + while ((block = parser.block_at_index(idx++))) { if (event_block_list_blocks_type(block->event_blocks, e.type)) return true; + } return event_block_list_blocks_type(parser.global_event_blocks, e.type); } @@ -321,12 +334,10 @@ void event_add_handler(const event_t &event) if (e->type == EVENT_SIGNAL) { signal_handle(e->param1.signal, 1); + set_signal_observed(e->param1.signal, true); } - // Block around updating the events vector - signal_block(); - events.push_back(e); - signal_unblock(); + s_event_handlers.push_back(e); } void event_remove(const event_t &criterion) @@ -348,12 +359,12 @@ void event_remove(const event_t &criterion) events-list. */ - if (events.empty()) + if (s_event_handlers.empty()) return; - for (size_t i=0; i<events.size(); i++) + for (size_t i=0; i<s_event_handlers.size(); i++) { - event_t *n = events.at(i); + event_t *n = s_event_handlers.at(i); if (event_match(criterion, *n)) { killme.push_back(n); @@ -369,6 +380,7 @@ void event_remove(const event_t &criterion) if (event_get(e, 0) == 1) { signal_handle(e.param1.signal, 0); + set_signal_observed(e.param1.signal, 0); } } } @@ -377,22 +389,15 @@ void event_remove(const event_t &criterion) new_list.push_back(n); } } - signal_block(); - events.swap(new_list); - signal_unblock(); + s_event_handlers.swap(new_list); } int event_get(const event_t &criterion, std::vector<event_t *> *out) { - size_t i; int found = 0; - - if (events.empty()) - return 0; - - for (i=0; i<events.size(); i++) + for (size_t i=0; i < s_event_handlers.size(); i++) { - event_t *n = events.at(i); + event_t *n = s_event_handlers.at(i); if (event_match(criterion, *n)) { found++; @@ -406,23 +411,13 @@ int event_get(const event_t &criterion, std::vector<event_t *> *out) bool event_is_signal_observed(int sig) { /* We are in a signal handler! Don't allocate memory, etc. - This does what event_match does, except it doesn't require passing in an event_t. */ - size_t i, max = events.size(); - for (i=0; i < max; i++) + bool result = false; + if (sig >= 0 && sig < sizeof s_observed_signals / sizeof *s_observed_signals) { - const event_t *event = events[i]; - if (event->type == EVENT_ANY) - { - return true; - } - else if (event->type == EVENT_SIGNAL) - { - if (event->param1.signal == EVENT_ANY_SIGNAL || event->param1.signal == sig) - return true; - } + result = s_observed_signals[sig]; } - return false; + return result; } /** @@ -470,7 +465,7 @@ static void event_fire_internal(const event_t &event) if (is_event <= 1) event_free_kills(); - if (events.empty()) + if (s_event_handlers.empty()) return; /* @@ -480,9 +475,9 @@ static void event_fire_internal(const event_t &event) event_add_handler, which will change the contents of the \c events list. */ - for (size_t i=0; i<events.size(); i++) + for (size_t i=0; i<s_event_handlers.size(); i++) { - event_t *criterion = events.at(i); + event_t *criterion = s_event_handlers.at(i); /* Check if this event is a match @@ -565,9 +560,6 @@ static void event_fire_internal(const event_t &event) */ static void event_fire_delayed() { - - size_t i; - /* If is_event is one, we are running the event-handler non-recursively. @@ -579,7 +571,7 @@ static void event_fire_delayed() { event_list_t new_blocked; - for (i=0; i<blocked.size(); i++) + for (size_t i=0; i<blocked.size(); i++) { event_t *e = blocked.at(i); if (event_is_blocked(*e)) @@ -695,8 +687,8 @@ void event_init() void event_destroy() { - for_each(events.begin(), events.end(), event_free); - events.clear(); + for_each(s_event_handlers.begin(), s_event_handlers.end(), event_free); + s_event_handlers.clear(); for_each(killme.begin(), killme.end(), event_free); killme.clear(); |