Beispiel #1
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);
}
Beispiel #2
0
t_callback	which_callback(t_lst *events_p, t_event event)
{
	t_callback	callback;
	t_event		mask;

	mask = T_EVENT(~0, NULL);
	callback = event_match(wrapper_event_match, events_p, &event, &mask);
	return (NULL);
}
static int
find_event(struct pevent *pevent, struct event_list **events,
	   char *sys_name, char *event_name)
{
	struct event_format *event;
	regex_t ereg;
	regex_t sreg;
	int match = 0;
	char *reg;
	int ret;
	int i;

	if (!event_name) {
		/* if no name is given, then swap sys and name */
		event_name = sys_name;
		sys_name = NULL;
	}

	reg = malloc_or_die(strlen(event_name) + 3);
	sprintf(reg, "^%s$", event_name);

	ret = regcomp(&ereg, reg, REG_ICASE|REG_NOSUB);
	free(reg);

	if (ret)
		return -1;

	if (sys_name) {
		reg = malloc_or_die(strlen(sys_name) + 3);
		sprintf(reg, "^%s$", sys_name);
		ret = regcomp(&sreg, reg, REG_ICASE|REG_NOSUB);
		free(reg);
		if (ret) {
			regfree(&ereg);
			return -1;
		}
	}

	for (i = 0; i < pevent->nr_events; i++) {
		event = pevent->events[i];
		if (event_match(event, sys_name ? &sreg : NULL, &ereg)) {
			match = 1;
			add_event(events, event);
		}
	}

	regfree(&ereg);
	if (sys_name)
		regfree(&sreg);

	if (!match)
		return -1;

	return 0;
}
Beispiel #4
0
int event_get(const event_t &criterion, std::vector<event_t *> *out) {
    int found = 0;
    for (size_t i = 0; i < s_event_handlers.size(); i++) {
        event_t *n = s_event_handlers.at(i);
        if (event_match(criterion, *n)) {
            found++;
            if (out) out->push_back(n);
        }
    }
    return found;
}
/**
 * matecomponent_event_source_notify_listeners:
 * @event_source: the Event Source that will emit the event.
 * @event_name: Name of the event being emitted
 * @opt_value: A CORBA_any value that contains the data that is passed
 * to interested clients, or NULL for an empty value
 * @opt_ev: A CORBA_Environment where a failure code can be returned, can be NULL.
 *
 * This will notify all clients that have registered with this EventSource
 * (through the addListener or addListenerWithMask methods) of the availability
 * of the event named @event_name.  The @value CORBA::any value is passed to
 * all listeners.
 *
 * @event_name can not contain comma separators, as commas are used to
 * separate the various event names. 
 */
void
matecomponent_event_source_notify_listeners (MateComponentEventSource *event_source,
				      const char        *event_name,
				      const CORBA_any   *opt_value,
				      CORBA_Environment *opt_ev)
{
	GSList *l, *notify;
	CORBA_Environment  *ev, temp_ev;
	const MateComponentArg *my_value;

	g_return_if_fail (MATECOMPONENT_IS_EVENT_SOURCE (event_source));
	
	if (!opt_ev) {
		CORBA_exception_init (&temp_ev);
		ev = &temp_ev;
	} else
		ev = opt_ev;

	if (!opt_value)
		my_value = matecomponent_arg_new (MATECOMPONENT_ARG_NULL);
	else
		my_value = opt_value;
	
	notify = NULL;

	for (l = event_source->priv->listeners; l; l = l->next) {
		ListenerDesc *desc = (ListenerDesc *) l->data;

		if (desc->event_masks == NULL || 
		    event_match (event_name, desc->event_masks)) {
			notify = g_slist_prepend (
				notify,
				CORBA_Object_duplicate (desc->listener, ev));
		}
	}

	matecomponent_object_ref (MATECOMPONENT_OBJECT (event_source));

	for (l = notify; l; l = l->next) {
		MateComponent_Listener_event (l->data, event_name, my_value, ev);
		CORBA_Object_release (l->data, ev);
	}

	matecomponent_object_unref (MATECOMPONENT_OBJECT (event_source));

	g_slist_free (notify);

	if (!opt_ev)
		CORBA_exception_free (ev);

	if (!opt_value)
		matecomponent_arg_release ((MateComponentArg *) my_value);
}
Beispiel #6
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();
}
Beispiel #7
0
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++)
    {
        event_t *n = events.at(i);
        if (event_match(criterion, *n))
        {
            found++;
            if (out)
                out->push_back(n);
        }
    }
    return found;
}
/**
 * matecomponent_event_source_has_listener:
 * @event_source: the Event Source that will emit the event.
 * @event_name: Name of the event being emitted
 * 
 *   This method determines if there are any listeners for
 * the event to be broadcast. This can be used to detect
 * whether it is worth constructing a potentialy expensive
 * state update, before sending it to no-one.
 * 
 * Return value: TRUE if it's worth sending, else FALSE
 **/
gboolean
matecomponent_event_source_has_listener (MateComponentEventSource *event_source,
				  const char        *event_name)
{
	GSList  *l;
	gboolean notify;

	g_return_val_if_fail (MATECOMPONENT_IS_EVENT_SOURCE (event_source), FALSE);

	notify = FALSE;
	for (l = event_source->priv->listeners; l; l = l->next) {
		ListenerDesc *desc = (ListenerDesc *) l->data;

		if (desc->event_masks == NULL || 
		    event_match (event_name, desc->event_masks)) {
			notify = TRUE;
			break;
		}
	}

	return notify;
}
Beispiel #9
0
/**
   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();

    if (events.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; i<events.size(); i++)
    {
        event_t *criterion = events.at(i);

        /*
          Check if this event is a match
        */
        if (event_match(*criterion, event))
        {
            fire.push_back(criterion);
        }
    }

    /*
      No matches. Time to return.
    */
    if (fire.empty())
        return;

    if (signal_is_blocked())
    {
        /* Fix for https://github.com/fish-shell/fish-shell/issues/608. Don't run event handlers while signals are blocked. */
        event_t *heap_event = new event_t(event);
        input_common_add_callback(fire_event_callback, heap_event);
        return;
    }

    /*
      Iterate over our list of matching events
    */

    for (size_t i=0; i<fire.size(); i++)
    {
        event_t *criterion = fire.at(i);
        int prev_status;

        /*
          Check if this event has been removed, if so, dont fire it
        */
        if (event_is_killed(*criterion))
            continue;

        /*
          Fire event
        */
        wcstring buffer = criterion->function_name;

        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;
        }

        // 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
        */
        proc_push_interactive(0);
        prev_status = proc_get_last_status();
        parser_t &parser = parser_t::principal_parser();

        block_t *block = new event_block_t(event);
        parser.push_block(block);
        parser.eval(buffer, io_chain_t(), TOP);
        parser.pop_block();
        proc_pop_interactive();
        proc_set_last_status(prev_status);
    }

    /*
      Free killed events
    */
    if (is_event <= 1)
        event_free_kills();

}
Beispiel #10
0
/**
   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)
{

    size_t i, j;
    event_list_t fire;

    /*
      First we free all events that have been removed
    */
    event_free_kills();

    if (events.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 (i=0; i<events.size(); i++)
    {
        event_t *criterion = events.at(i);

        /*
          Check if this event is a match
        */
        if (event_match(criterion, event))
        {
            fire.push_back(criterion);
        }
    }

    /*
      No matches. Time to return.
    */
    if (fire.empty())
        return;

    /*
      Iterate over our list of matching events
    */

    for (i=0; i<fire.size(); i++)
    {
        event_t *criterion = fire.at(i);
        int prev_status;

        /*
          Check if this event has been removed, if so, dont fire it
        */
        if (event_is_killed(criterion))
            continue;

        /*
          Fire event
        */
        wcstring buffer = criterion->function_name;

        if (event->arguments.get())
        {
            for (j=0; j< event->arguments->size(); j++)
            {
                wcstring arg_esc = escape_string(event->arguments->at(j), 1);
                buffer += L" ";
                buffer += arg_esc;
            }
        }

//    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
        */
        proc_push_interactive(0);
        prev_status = proc_get_last_status();
        parser_t &parser = parser_t::principal_parser();

        block_t *block = new event_block_t(event);
        parser.push_block(block);
        parser.eval(buffer, io_chain_t(), TOP);
        parser.pop_block();
        proc_pop_interactive();
        proc_set_last_status(prev_status);
    }

    /*
      Free killed events
    */
    event_free_kills();

}
Beispiel #11
0
int			wrapper_event_match(t_event *elem1, t_event *elem2, t_event *mask)
{
	return (event_match(*elem1, *elem2, mask));
}