From 32c241f51be281043aa1e30ca3fb9b277cd28d6b Mon Sep 17 00:00:00 2001 From: Kurtis Rader Date: Thu, 28 Apr 2016 19:19:50 -0700 Subject: retyle event module to match project style Reduces lint errors from 39 to 30 (-23%). Line count from 915 to 670 (-27%). Another step in resolving issue #2902. --- src/event.cpp | 646 ++++++++++++++++++++-------------------------------------- 1 file changed, 220 insertions(+), 426 deletions(-) (limited to 'src/event.cpp') diff --git a/src/event.cpp b/src/event.cpp index ee1d7c0a..26579101 100644 --- a/src/event.cpp +++ b/src/event.cpp @@ -1,226 +1,164 @@ -/** \file event.c - - Functions for handling event triggers -*/ -#include +// Functions for handling event triggers. #include +#include +#include #include -#include #include +#include #include -#include -#include "fallback.h" // IWYU pragma: keep -#include "wutil.h" // IWYU pragma: keep -#include "input_common.h" -#include "proc.h" -#include "parser.h" #include "common.h" #include "event.h" -#include "signal.h" +#include "fallback.h" // IWYU pragma: keep +#include "input_common.h" #include "io.h" +#include "parser.h" +#include "proc.h" +#include "signal.h" +#include "wutil.h" // IWYU pragma: keep -/** - Number of signals that can be queued before an overflow occurs -*/ +/// Number of signals that can be queued before an overflow occurs. #define SIG_UNHANDLED_MAX 64 -/** - This struct contains a list of generated signals waiting to be - dispatched -*/ -typedef struct -{ - /** - Number of delivered signals - */ +/// This struct contains a list of generated signals waiting to be dispatched. +typedef struct { + /// Number of delivered signals. volatile int count; - /** - Whether signals have been skipped - */ + /// Whether signals have been skipped. volatile int overflow; - /** - Array of signal events - */ + /// Array of signal events. volatile int signal[SIG_UNHANDLED_MAX]; -} -signal_list_t; +} signal_list_t; -/** - The signal event list. Actually two separate lists. One which is - 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[2]= {{},{}}; +/// The signal event list. Actually two separate lists. One which is 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[2] = {{}, {}}; -/** - The index of sig_list that is the list of signals currently written to -*/ -static volatile int active_list=0; +/// The index of sig_list that is the list of signals currently written to. +static volatile int active_list = 0; typedef std::vector event_list_t; -/** - List of event handlers. -*/ +/// List of event handlers. static event_list_t s_event_handlers; -/** - List of event handlers that should be removed -*/ +/// List of event handlers that should be removed. static event_list_t killme; -/** - List of events that have been sent but have not yet been delivered because they are blocked. -*/ +/// List of events that have been sent but have not yet been delivered because they are blocked. static event_list_t blocked; -/** Variables (one per signal) set when a signal is observed. This is inspected by a signal handler. */ +/// 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) -{ +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) - { + 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, - they must name the same function. - -*/ -static int event_match(const event_t &classv, const event_t &instance) -{ - - /* If the function names are both non-empty and different, then it's not a match */ - if (! classv.function_name.empty() && - ! instance.function_name.empty() && - classv.function_name != instance.function_name) - { +/// Tests if one event instance matches the definition of a event class. If both the class and the +/// instance name a function, they must name the same function. +static int event_match(const event_t &classv, const event_t &instance) { + // If the function names are both non-empty and different, then it's not a match. + if (!classv.function_name.empty() && !instance.function_name.empty() && + classv.function_name != instance.function_name) { return 0; } - if (classv.type == EVENT_ANY) - return 1; - - if (classv.type != instance.type) - return 0; - - - switch (classv.type) - { + if (classv.type == EVENT_ANY) return 1; + if (classv.type != instance.type) return 0; - case EVENT_SIGNAL: - if (classv.param1.signal == EVENT_ANY_SIGNAL) - return 1; + switch (classv.type) { + case EVENT_SIGNAL: { + if (classv.param1.signal == EVENT_ANY_SIGNAL) return 1; return classv.param1.signal == instance.param1.signal; - - case EVENT_VARIABLE: + } + case EVENT_VARIABLE: { return instance.str_param1 == classv.str_param1; - - case EVENT_EXIT: - if (classv.param1.pid == EVENT_ANY_PID) - return 1; + } + case EVENT_EXIT: { + if (classv.param1.pid == EVENT_ANY_PID) return 1; return classv.param1.pid == instance.param1.pid; - - case EVENT_JOB_ID: + } + case EVENT_JOB_ID: { return classv.param1.job_id == instance.param1.job_id; - - case EVENT_GENERIC: + } + case EVENT_GENERIC: { return instance.str_param1 == classv.str_param1; - + } } - /** - This should never be reached - */ + // This should never be reached. debug(0, "Warning: Unreachable code reached in event_match in event.cpp\n"); return 0; } - - -/** - Test if specified event is blocked -*/ -static int event_is_blocked(const event_t &e) -{ +/// Test if specified event is blocked. +static int event_is_blocked(const event_t &e) { const block_t *block; parser_t &parser = parser_t::principal_parser(); size_t idx = 0; - while ((block = parser.block_at_index(idx++))) - { - if (event_block_list_blocks_type(block->event_blocks, e.type)) - return true; - + 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); } -wcstring event_get_desc(const event_t &e) -{ - +wcstring event_get_desc(const event_t &e) { wcstring result; - switch (e.type) - { - - case EVENT_SIGNAL: - result = format_string(_(L"signal handler for %ls (%ls)"), sig2wcs(e.param1.signal), signal_get_desc(e.param1.signal)); + switch (e.type) { + case EVENT_SIGNAL: { + result = format_string(_(L"signal handler for %ls (%ls)"), sig2wcs(e.param1.signal), + signal_get_desc(e.param1.signal)); break; - - case EVENT_VARIABLE: + } + case EVENT_VARIABLE: { result = format_string(_(L"handler for variable '%ls'"), e.str_param1.c_str()); break; - - case EVENT_EXIT: - if (e.param1.pid > 0) - { + } + case EVENT_EXIT: { + if (e.param1.pid > 0) { result = format_string(_(L"exit handler for process %d"), e.param1.pid); - } - else - { + } else { job_t *j = job_get_from_pid(-e.param1.pid); if (j) - result = format_string(_(L"exit handler for job %d, '%ls'"), j->job_id, j->command_wcstr()); + result = format_string(_(L"exit handler for job %d, '%ls'"), j->job_id, + j->command_wcstr()); else - result = format_string(_(L"exit handler for job with process group %d"), -e.param1.pid); + result = format_string(_(L"exit handler for job with process group %d"), + -e.param1.pid); } - break; - - case EVENT_JOB_ID: - { + } + case EVENT_JOB_ID: { job_t *j = job_get(e.param1.job_id); - if (j) - result = format_string(_(L"exit handler for job %d, '%ls'"), j->job_id, j->command_wcstr()); - else + if (j) { + result = format_string(_(L"exit handler for job %d, '%ls'"), j->job_id, + j->command_wcstr()); + } else { result = format_string(_(L"exit handler for job with job id %d"), e.param1.job_id); - + } break; } - - case EVENT_GENERIC: + case EVENT_GENERIC: { result = format_string(_(L"handler for generic event '%ls'"), e.str_param1.c_str()); break; - - default: + } + default: { result = format_string(_(L"Unknown event type '0x%x'"), e.type); break; - + } } return result; } #if 0 -static void show_all_handlers(void) -{ +static void show_all_handlers(void) { puts("event handlers:"); - for (event_list_t::const_iterator iter = events.begin(); iter != events.end(); ++iter) - { + for (event_list_t::const_iterator iter = events.begin(); iter != events.end(); ++iter) { const event_t *foo = *iter; wcstring tmp = event_get_desc(foo); printf(" handler now %ls\n", tmp.c_str()); @@ -228,104 +166,84 @@ static void show_all_handlers(void) } #endif -/* - Give a more condensed description of \c event compared to \c event_get_desc. - It includes what function will fire if the \c event is an event handler. - */ -static wcstring event_desc_compact(const event_t &event) -{ +/// Give a more condensed description of \c event compared to \c event_get_desc. It includes what +/// function will fire if the \c event is an event handler. +static wcstring event_desc_compact(const event_t &event) { wcstring res; wchar_t const *temp; int sig; - switch (event.type) - { - case EVENT_ANY: + switch (event.type) { + case EVENT_ANY: { res = L"EVENT_ANY"; break; - case EVENT_VARIABLE: - if (event.str_param1.c_str()) - { + } + case EVENT_VARIABLE: { + if (event.str_param1.c_str()) { res = format_string(L"EVENT_VARIABLE($%ls)", event.str_param1.c_str()); - } - else - { + } else { res = L"EVENT_VARIABLE([any])"; } break; - case EVENT_SIGNAL: + } + case EVENT_SIGNAL: { sig = event.param1.signal; - if (sig == EVENT_ANY_SIGNAL) - { + if (sig == EVENT_ANY_SIGNAL) { temp = L"[all signals]"; - } - else if (sig == 0) - { + } else if (sig == 0) { temp = L"not set"; - } - else - { + } else { temp = sig2wcs(sig); } res = format_string(L"EVENT_SIGNAL(%ls)", temp); break; - case EVENT_EXIT: - if (event.param1.pid == EVENT_ANY_PID) - { + } + case EVENT_EXIT: { + if (event.param1.pid == EVENT_ANY_PID) { res = wcstring(L"EVENT_EXIT([all child processes])"); - } - else if (event.param1.pid > 0) - { + } else if (event.param1.pid > 0) { res = format_string(L"EVENT_EXIT(pid %d)", event.param1.pid); - } - else - { + } else { job_t *j = job_get_from_pid(-event.param1.pid); if (j) - res = format_string(L"EVENT_EXIT(jobid %d: \"%ls\")", j->job_id, j->command_wcstr()); + res = format_string(L"EVENT_EXIT(jobid %d: \"%ls\")", j->job_id, + j->command_wcstr()); else res = format_string(L"EVENT_EXIT(pgid %d)", -event.param1.pid); } break; - case EVENT_JOB_ID: - { + } + case EVENT_JOB_ID: { job_t *j = job_get(event.param1.job_id); if (j) - res = format_string(L"EVENT_JOB_ID(job %d: \"%ls\")", j->job_id, j->command_wcstr()); + res = + format_string(L"EVENT_JOB_ID(job %d: \"%ls\")", j->job_id, j->command_wcstr()); else res = format_string(L"EVENT_JOB_ID(jobid %d)", event.param1.job_id); break; } - case EVENT_GENERIC: + case EVENT_GENERIC: { res = format_string(L"EVENT_GENERIC(%ls)", event.str_param1.c_str()); break; - default: - res = format_string(L"unknown/illegal event(%x)", event.type); + } + default: { res = format_string(L"unknown/illegal event(%x)", event.type); } } - if (event.function_name.size()) - { + if (event.function_name.size()) { return format_string(L"%ls: \"%ls\"", res.c_str(), event.function_name.c_str()); - } - else - { + } else { return res; } } - -void event_add_handler(const event_t &event) -{ +void event_add_handler(const event_t &event) { event_t *e; - if (debug_level >= 3) - { + if (debug_level >= 3) { wcstring desc = event_desc_compact(event); debug(3, "register: %ls\n", desc.c_str()); } e = new event_t(event); - - if (e->type == EVENT_SIGNAL) - { + if (e->type == EVENT_SIGNAL) { signal_handle(e->param1.signal, 1); set_signal_observed(e->param1.signal, true); } @@ -333,106 +251,75 @@ void event_add_handler(const event_t &event) s_event_handlers.push_back(e); } -void event_remove(const event_t &criterion) -{ +void event_remove(const event_t &criterion) { event_list_t new_list; - if (debug_level >= 3) - { + if (debug_level >= 3) { wcstring desc = event_desc_compact(criterion); debug(3, "unregister: %ls\n", desc.c_str()); } - /* - Because of concurrency issues (env_remove could remove an event - that is currently being executed), env_remove does not actually - free any events - instead it simply moves all events that should - be removed from the event list to the killme list, and the ones - that shouldn't be killed to new_list, and then drops the empty - events-list. - */ - - if (s_event_handlers.empty()) - return; + // Because of concurrency issues (env_remove could remove an event that is currently being + // executed), env_remove does not actually free any events - instead it simply moves all events + // that should be removed from the event list to the killme list, and the ones that shouldn't be + // killed to new_list, and then drops the empty events-list. + if (s_event_handlers.empty()) return; - for (size_t i=0; itype == EVENT_SIGNAL) - { + // If this event was a signal handler and no other handler handles the specified signal + // type, do not handle that type of signal any more. + if (n->type == EVENT_SIGNAL) { event_t e = event_t::signal_event(n->param1.signal); - if (event_get(e, 0) == 1) - { + if (event_get(e, 0) == 1) { signal_handle(e.param1.signal, 0); set_signal_observed(e.param1.signal, 0); } } - } - else - { + } else { new_list.push_back(n); } } s_event_handlers.swap(new_list); } -int event_get(const event_t &criterion, std::vector *out) -{ +int event_get(const event_t &criterion, std::vector *out) { int found = 0; - for (size_t i=0; i < s_event_handlers.size(); i++) - { + for (size_t i = 0; i < s_event_handlers.size(); i++) { event_t *n = s_event_handlers.at(i); - if (event_match(criterion, *n)) - { + if (event_match(criterion, *n)) { found++; - if (out) - out->push_back(n); + if (out) out->push_back(n); } } return found; } -bool event_is_signal_observed(int sig) -{ - /* We are in a signal handler! Don't allocate memory, etc. - */ +bool event_is_signal_observed(int sig) { + // We are in a signal handler! Don't allocate memory, etc. bool result = false; - if (sig >= 0 && sig < sizeof s_observed_signals / sizeof *s_observed_signals) - { + if (sig >= 0 && sig < sizeof s_observed_signals / sizeof *s_observed_signals) { result = s_observed_signals[sig]; } return result; } -/** - Free all events in the kill list -*/ -static void event_free_kills() -{ +/// Free all events in the kill list. +static void event_free_kills() { for_each(killme.begin(), killme.end(), event_free); killme.resize(0); } -/** - Test if the specified event is waiting to be killed -*/ -static int event_is_killed(const event_t &e) -{ +/// Test if the specified event is waiting to be killed. +static int event_is_killed(const event_t &e) { return std::find(killme.begin(), killme.end(), &e) != killme.end(); } -/* Callback for firing (and then deleting) an event */ -static void fire_event_callback(void *arg) -{ +/// Callback for firing (and then deleting) an event. +static void fire_event_callback(void *arg) { ASSERT_IS_MAIN_THREAD(); assert(arg != NULL); event_t *event = static_cast(arg); @@ -440,83 +327,53 @@ static void fire_event_callback(void *arg) delete event; } -/** - Perform the specified event. Since almost all event firings will - not be matched by even a single event handler, we make sure to - optimize the 'no matches' path. This means that nothing is - allocated/initialized unless needed. -*/ -static void event_fire_internal(const event_t &event) -{ - +/// Perform the specified event. Since almost all event firings will not be matched by even a single +/// event handler, we make sure to optimize the 'no matches' path. This means that nothing is +/// allocated/initialized unless needed. +static void event_fire_internal(const event_t &event) { event_list_t fire; - /* - First we free all events that have been removed, but only if this - invocation of event_fire_internal is not a recursive call. - */ - if (is_event <= 1) - event_free_kills(); + // First we free all events that have been removed, but only if this invocation of + // event_fire_internal is not a recursive call. + if (is_event <= 1) event_free_kills(); - if (s_event_handlers.empty()) - return; + if (s_event_handlers.empty()) return; - /* - Then we iterate over all events, adding events that should be - fired to a second list. We need to do this in a separate step - since an event handler might call event_remove or - event_add_handler, which will change the contents of the \c - events list. - */ - for (size_t i=0; ifunction_name; - for (size_t j=0; j < event.arguments.size(); j++) - { + for (size_t j = 0; j < event.arguments.size(); j++) { wcstring arg_esc = escape_string(event.arguments.at(j), 1); buffer += L" "; buffer += arg_esc; @@ -524,10 +381,8 @@ static void event_fire_internal(const event_t &event) // debug( 1, L"Event handler fires command '%ls'", buffer.c_str() ); - /* - Event handlers are not part of the main flow of code, so - they are marked as non-interactive - */ + // Event handlers are not part of the main flow of code, so they are marked as + // non-interactive. proc_push_interactive(0); prev_status = proc_get_last_status(); parser_t &parser = parser_t::principal_parser(); @@ -540,39 +395,24 @@ static void event_fire_internal(const event_t &event) proc_set_last_status(prev_status); } - /* - Free killed events - */ - if (is_event <= 1) - event_free_kills(); - + // Free killed events. + if (is_event <= 1) event_free_kills(); } -/** - Handle all pending signal events -*/ -static void event_fire_delayed() -{ - /* - If is_event is one, we are running the event-handler non-recursively. - - When the event handler has called a piece of code that triggers - another event, we do not want to fire delayed events because of - concurrency problems. - */ - if (! blocked.empty() && is_event==1) - { +/// Handle all pending signal events. +static void event_fire_delayed() { + // If is_event is one, we are running the event-handler non-recursively. + // + // When the event handler has called a piece of code that triggers another event, we do not want + // to fire delayed events because of concurrency problems. + if (!blocked.empty() && is_event == 1) { event_list_t new_blocked; - for (size_t i=0; i 0) - { + while (sig_list[al].count > 0) { signal_list_t *lst; - /* - Switch signal lists - */ - sig_list[1-al].count=0; - sig_list[1-al].overflow=0; - al = 1-al; - active_list=al; - - /* - Set up - */ - lst = &sig_list[1-al]; + // Switch signal lists. + sig_list[1 - al].count = 0; + sig_list[1 - al].overflow = 0; + al = 1 - al; + active_list = al; + + // Set up. + lst = &sig_list[1 - al]; event_t e = event_t::signal_event(0); e.arguments.resize(1); - if (lst->overflow) - { + if (lst->overflow) { debug(0, _(L"Signal list overflow. Signals have been ignored.")); } - /* - Send all signals in our private list - */ - for (int i=0; i < lst->count; i++) - { + // Send all signals in our private list. + for (int i = 0; i < lst->count; i++) { e.param1.signal = lst->signal[i]; e.arguments.at(0) = sig2wcs(e.param1.signal); - if (event_is_blocked(e)) - { + if (event_is_blocked(e)) { blocked.push_back(new event_t(e)); - } - else - { + } else { event_fire_internal(e); } } - } } -void event_fire_signal(int signal) -{ - /* - This means we are in a signal handler. We must be very - careful not do do anything that could cause a memory - allocation or something else that might be bad when in a - signal handler. - */ +void event_fire_signal(int signal) { + // This means we are in a signal handler. We must be very careful not do do anything that could + // cause a memory allocation or something else that might be bad when in a signal handler. if (sig_list[active_list].count < SIG_UNHANDLED_MAX) - sig_list[active_list].signal[sig_list[active_list].count++]=signal; + sig_list[active_list].signal[sig_list[active_list].count++] = signal; else - sig_list[active_list].overflow=1; + sig_list[active_list].overflow = 1; } - -void event_fire(const event_t *event) -{ - - if (event && event->type == EVENT_SIGNAL) - { +void event_fire(const event_t *event) { + if (event && event->type == EVENT_SIGNAL) { event_fire_signal(event->param1.signal); - } - else - { + } else { is_event++; - /* - Fire events triggered by signals - */ + // Fire events triggered by signals. event_fire_delayed(); - if (event) - { - if (event_is_blocked(*event)) - { + if (event) { + if (event_is_blocked(*event)) { blocked.push_back(new event_t(*event)); - } - else - { + } else { event_fire_internal(*event); } } @@ -672,14 +482,9 @@ void event_fire(const event_t *event) } } +void event_init() {} -void event_init() -{ -} - -void event_destroy() -{ - +void event_destroy() { for_each(s_event_handlers.begin(), s_event_handlers.end(), event_free); s_event_handlers.clear(); @@ -687,49 +492,38 @@ void event_destroy() killme.clear(); } -void event_free(event_t *e) -{ - CHECK(e,); +void event_free(event_t *e) { + CHECK(e, ); delete e; } -void event_fire_generic(const wchar_t *name, wcstring_list_t *args) -{ - CHECK(name,); +void event_fire_generic(const wchar_t *name, wcstring_list_t *args) { + CHECK(name, ); event_t ev(EVENT_GENERIC); ev.str_param1 = name; - if (args) - ev.arguments = *args; + if (args) ev.arguments = *args; event_fire(&ev); } -event_t::event_t(int t) : type(t), param1(), str_param1(), function_name(), arguments() -{ -} +event_t::event_t(int t) : type(t), param1(), str_param1(), function_name(), arguments() {} -event_t::~event_t() -{ -} +event_t::~event_t() {} -event_t event_t::signal_event(int sig) -{ +event_t event_t::signal_event(int sig) { event_t event(EVENT_SIGNAL); event.param1.signal = sig; return event; } -event_t event_t::variable_event(const wcstring &str) -{ +event_t event_t::variable_event(const wcstring &str) { event_t event(EVENT_VARIABLE); event.str_param1 = str; return event; } -event_t event_t::generic_event(const wcstring &str) -{ +event_t event_t::generic_event(const wcstring &str) { event_t event(EVENT_GENERIC); event.str_param1 = str; return event; } - -- cgit v1.2.3