Esempio n. 1
0
void event_fire(const event_t *event)
{

    if (event && event->type == EVENT_SIGNAL)
    {
        event_fire_signal(event->param1.signal);
    }
    else
    {
        is_event++;

        /*
          Fire events triggered by signals
        */
        event_fire_delayed();

        if (event)
        {
            if (event_is_blocked(*event))
            {
                blocked.push_back(new event_t(*event));
            }
            else
            {
                event_fire_internal(*event);
            }
        }
        is_event--;
    }
}
Esempio n. 2
0
void event_remove(const event_t &criterion) {
    event_list_t new_list;

    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;

    for (size_t i = 0; i < s_event_handlers.size(); i++) {
        event_t *n = s_event_handlers.at(i);
        if (event_match(criterion, *n)) {
            killme.push_back(n);

            // 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) {
                    signal_handle(e.param1.signal, 0);
                    set_signal_observed(e.param1.signal, 0);
                }
            }
        } else {
            new_list.push_back(n);
        }
    }
    s_event_handlers.swap(new_list);
}
Esempio n. 3
0
/// 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 < blocked.size(); i++) {
            event_t *e = blocked.at(i);
            if (event_is_blocked(*e)) {
                new_blocked.push_back(new event_t(*e));
            } else {
                event_fire_internal(*e);
                event_free(e);
            }
        }
        blocked.swap(new_blocked);
    }

    int al = active_list;

    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];
        event_t e = event_t::signal_event(0);
        e.arguments.resize(1);

        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++) {
            e.param1.signal = lst->signal[i];
            e.arguments.at(0) = sig2wcs(e.param1.signal);
            if (event_is_blocked(e)) {
                blocked.push_back(new event_t(e));
            } else {
                event_fire_internal(e);
            }
        }
    }
}
Esempio n. 4
0
void event_remove(event_t *criterion)
{

    size_t i;
    event_list_t new_list;

    CHECK(criterion,);

    /*
      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 (events.empty())
        return;

    for (i=0; i<events.size(); i++)
    {
        event_t *n = events.at(i);
        if (event_match(criterion, n))
        {
            killme.push_back(n);

            /*
              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)
                {
                    signal_handle(e.param1.signal, 0);
                }
            }
        }
        else
        {
            new_list.push_back(n);
        }
    }
    signal_block();
    events.swap(new_list);
    signal_unblock();
}
Esempio n. 5
0
void event_add_handler(const event_t &event) {
    event_t *e;

    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) {
        signal_handle(e->param1.signal, 1);
        set_signal_observed(e->param1.signal, true);
    }

    s_event_handlers.push_back(e);
}
Esempio n. 6
0
void event_add_handler(const event_t *event)
{
    event_t *e;

    CHECK(event,);

    e = event_copy(event, 0);

    if (e->type == EVENT_SIGNAL)
    {
        signal_handle(e->param1.signal, 1);
    }

    // Block around updating the events vector
    signal_block();
    events.push_back(e);
    signal_unblock();
}
Esempio n. 7
0
void event_add_handler(const event_t &event)
{
    event_t *e;

    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)
    {
        signal_handle(e->param1.signal, 1);
    }

    // Block around updating the events vector
    signal_block();
    events.push_back(e);
    signal_unblock();
}
Esempio n. 8
0
/**
   Handle all pending signal events
*/
static void event_fire_delayed()
{

    size_t i;

    /*
      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 (i=0; i<blocked.size(); i++)
        {
            event_t *e = blocked.at(i);
            if (event_is_blocked(e))
            {
                new_blocked.push_back(e);
            }
            else
            {
                event_fire_internal(e);
                event_free(e);
            }
        }
        blocked.swap(new_blocked);
    }

    while (sig_list[active_list].count > 0)
    {
        signal_list_t *lst;

        /*
          Switch signal lists
        */
        sig_list[1-active_list].count=0;
        sig_list[1-active_list].overflow=0;
        active_list=1-active_list;

        /*
          Set up
        */
        event_t e = event_t::signal_event(0);
        e.arguments.reset(new wcstring_list_t(1)); //one element
        lst = &sig_list[1-active_list];

        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++)
        {
            e.param1.signal = lst->signal[i];
            e.arguments->at(0) = sig2wcs(e.param1.signal);
            if (event_is_blocked(&e))
            {
                blocked.push_back(event_copy(&e, 1));
            }
            else
            {
                event_fire_internal(&e);
            }
        }

        e.arguments.reset(NULL);

    }
}