aboutsummaryrefslogtreecommitdiffhomepage
path: root/event.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'event.cpp')
-rw-r--r--event.cpp82
1 files changed, 37 insertions, 45 deletions
diff --git a/event.cpp b/event.cpp
index f6313fb0..14def5f4 100644
--- a/event.cpp
+++ b/event.cpp
@@ -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();