event-dispatcher: after-events hooks to get the trigger event info
after-events hooks will get the original event triggering it, instead of the rescan event. after-events hook can register with any event, but it is called with rescan event info. This is so because, after-events hook run after all the on-events hooks are done with and as a part of the rescan event. so it is triggered with rescan event data, which doesnt carry much info, instead of rescan event, it makes more sense to call the after-events hook with the original event which triggered it.
This commit is contained in:

committed by
Julian Bouzas

parent
72226e3934
commit
3ff9f240c8
@@ -200,6 +200,7 @@ void
|
||||
wp_event_stop_processing (WpEvent * self)
|
||||
{
|
||||
g_return_if_fail (self != NULL);
|
||||
wp_debug ("stopping event(%s)", self->name);
|
||||
g_cancellable_cancel (self->cancellable);
|
||||
}
|
||||
|
||||
@@ -250,6 +251,9 @@ on_event_hook_done (WpEventHook * hook, GAsyncResult * res, WpEvent * event)
|
||||
error->domain != G_IO_ERROR && error->code != G_IO_ERROR_CANCELLED)
|
||||
wp_message_object (hook, "failed: %s", error->message);
|
||||
|
||||
if (dispatcher->rescan_event == event)
|
||||
wp_event_hook_set_event (event->current_hook_in_async, NULL);
|
||||
|
||||
g_clear_object (&event->current_hook_in_async);
|
||||
spa_system_eventfd_write (dispatcher->system, dispatcher->eventfd, 1);
|
||||
}
|
||||
@@ -284,8 +288,10 @@ wp_event_source_dispatch (GSource * s, GSourceFunc callback, gpointer user_data)
|
||||
return G_SOURCE_CONTINUE;
|
||||
|
||||
/* remove the remaining hooks if the event was cancelled */
|
||||
if (g_cancellable_is_cancelled (event->cancellable) && event->hooks)
|
||||
if (g_cancellable_is_cancelled (event->cancellable) && event->hooks) {
|
||||
wp_debug_object (d, "event(%s) cancelled remove it", event->name);
|
||||
g_list_free_full (g_steal_pointer (&event->hooks), g_object_unref);
|
||||
}
|
||||
|
||||
/* avoid duplicate entries in chain */
|
||||
if (!d->events_chain || !strstr (d->events_chain, event->name)) {
|
||||
@@ -300,6 +306,7 @@ wp_event_source_dispatch (GSource * s, GSourceFunc callback, gpointer user_data)
|
||||
if (lhook) {
|
||||
gchar *name = NULL;
|
||||
gint priority;
|
||||
|
||||
event->current_hook_in_async = WP_EVENT_HOOK (lhook->data);
|
||||
event->hooks = g_list_delete_link (event->hooks, g_steal_pointer (&lhook));
|
||||
name = wp_event_hook_get_name (event->current_hook_in_async);
|
||||
@@ -309,6 +316,20 @@ wp_event_source_dispatch (GSource * s, GSourceFunc callback, gpointer user_data)
|
||||
wp_debug_object (d, "running hook <%p>(%s) and hooks chain (%s)",
|
||||
event->current_hook_in_async, name, event->hooks_chain);
|
||||
|
||||
if (event == d->rescan_event) {
|
||||
WpEvent *hook_event =
|
||||
wp_event_hook_get_event (event->current_hook_in_async);
|
||||
|
||||
/* for after-events, check if the corresponding event is cancelled */
|
||||
if (g_cancellable_is_cancelled (hook_event->cancellable))
|
||||
wp_debug_object (d, "remove hook(%s) as its trigger event(%s)"
|
||||
" is cancelled", name, hook_event->name);
|
||||
else
|
||||
wp_event_hook_run (event->current_hook_in_async, hook_event,
|
||||
event->cancellable, (GAsyncReadyCallback) on_event_hook_done,
|
||||
event);
|
||||
}
|
||||
else
|
||||
/* execute the hook, possibly async */
|
||||
wp_event_hook_run (event->current_hook_in_async, event,
|
||||
event->cancellable, (GAsyncReadyCallback) on_event_hook_done, event);
|
||||
@@ -481,6 +502,8 @@ wp_event_dispatcher_push_event (WpEventDispatcher * self, WpEvent * event)
|
||||
(GCompareFunc) hook_cmp_func);
|
||||
wp_debug_object (self, "added rescan hook <%p>(%s(%d))", hook,
|
||||
wp_event_hook_get_name (hook), wp_event_hook_get_priority (hook));
|
||||
|
||||
wp_event_hook_set_event (hook, event);
|
||||
rescan_hooks_added = true;
|
||||
}
|
||||
}
|
||||
|
@@ -21,6 +21,8 @@ struct _WpEventHookPrivate
|
||||
WpEventHookExecType exec_type;
|
||||
GWeakRef dispatcher;
|
||||
gchar *name;
|
||||
/* event triggering the hook, useful for after-events. */
|
||||
WpEvent *event_trigger;
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -47,6 +49,7 @@ wp_event_hook_finalize (GObject * object)
|
||||
WpEventHookPrivate *priv = wp_event_hook_get_instance_private (self);
|
||||
|
||||
g_weak_ref_clear (&priv->dispatcher);
|
||||
g_clear_pointer (&priv->event_trigger, wp_event_unref);
|
||||
g_free (priv->name);
|
||||
|
||||
G_OBJECT_CLASS (wp_event_hook_parent_class)->finalize (object);
|
||||
@@ -130,6 +133,38 @@ wp_event_hook_class_init (WpEventHookClass * klass)
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the event triggering the hook, this data is useful for
|
||||
* after-events.
|
||||
*
|
||||
* \ingroup wpeventhook
|
||||
* \param self the event hook
|
||||
* \returns (transfer none) (nullable): the event
|
||||
*/
|
||||
WpEvent *
|
||||
wp_event_hook_get_event (WpEventHook *self)
|
||||
{
|
||||
g_return_val_if_fail (WP_IS_EVENT_HOOK (self), 0);
|
||||
WpEventHookPrivate *priv = wp_event_hook_get_instance_private (self);
|
||||
return priv->event_trigger;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the event triggering the hook
|
||||
*
|
||||
* \ingroup wpeventhook
|
||||
* \param self the event hook
|
||||
* \param event (transfer none) (nullable):the event associated with the hook
|
||||
*/
|
||||
void
|
||||
wp_event_hook_set_event (WpEventHook *self, WpEvent *event)
|
||||
{
|
||||
WpEventHookPrivate *priv = wp_event_hook_get_instance_private (self);
|
||||
g_clear_pointer (&priv->event_trigger, wp_event_unref);
|
||||
if (event)
|
||||
priv->event_trigger = wp_event_ref (event);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the priority of the hook
|
||||
*
|
||||
@@ -191,6 +226,14 @@ wp_event_hook_get_dispatcher (WpEventHook * self)
|
||||
return g_weak_ref_get (&priv->dispatcher);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Sets the dispatcher to the hook
|
||||
*
|
||||
* \ingroup wpeventhook
|
||||
* \param self the event hook
|
||||
* \param dispatcher (transfer none) (nullable) dispatcher to which the hook is
|
||||
* to be registered.
|
||||
*/
|
||||
void
|
||||
wp_event_hook_set_dispatcher (WpEventHook * self, WpEventDispatcher * dispatcher)
|
||||
{
|
||||
|
@@ -29,8 +29,15 @@ typedef enum
|
||||
{
|
||||
WP_EVENT_HOOK_DEFAULT_PRIORITY_BASE = 0,
|
||||
|
||||
WP_EVENT_HOOK_DEFAULT_PRIORITY_RESCAN_POLICY = WP_EVENT_HOOK_DEFAULT_PRIORITY_BASE,
|
||||
WP_EVENT_HOOK_DEFAULT_PRIORITY_AFTER_EVENTS_DEFAULT_NODES_STATE_SAVE = WP_EVENT_HOOK_DEFAULT_PRIORITY_RESCAN_POLICY + PRIORITY_STEP, WP_EVENT_HOOK_DEFAULT_PRIORITY_RESCAN_DEFAULT_NODES = WP_EVENT_HOOK_DEFAULT_PRIORITY_AFTER_EVENTS_DEFAULT_NODES_STATE_SAVE + PRIORITY_STEP,
|
||||
WP_EVENT_HOOK_DEFAULT_PRIORITY_FIND_DEFINED_TARGET = WP_EVENT_HOOK_DEFAULT_PRIORITY_BASE,
|
||||
WP_EVENT_HOOK_DEFAULT_PRIORITY_FIND_UNDEFINED_TARGET = WP_EVENT_HOOK_DEFAULT_PRIORITY_FIND_DEFINED_TARGET + PRIORITY_STEP,
|
||||
WP_EVENT_HOOK_DEFAULT_PRIORITY_FIND_BEST_TARGET = WP_EVENT_HOOK_DEFAULT_PRIORITY_FIND_UNDEFINED_TARGET + PRIORITY_STEP,
|
||||
WP_EVENT_HOOK_DEFAULT_PRIORITY_PREPARE_LINK = WP_EVENT_HOOK_DEFAULT_PRIORITY_FIND_BEST_TARGET + PRIORITY_STEP,
|
||||
WP_EVENT_HOOK_DEFAULT_PRIORITY_CREATE_LINK = WP_EVENT_HOOK_DEFAULT_PRIORITY_PREPARE_LINK + PRIORITY_STEP,
|
||||
|
||||
WP_EVENT_HOOK_DEFAULT_PRIORITY_RESCAN_POLICY = WP_EVENT_HOOK_DEFAULT_PRIORITY_CREATE_LINK + PRIORITY_STEP,
|
||||
WP_EVENT_HOOK_DEFAULT_PRIORITY_AFTER_EVENTS_DEFAULT_NODES_STATE_SAVE = WP_EVENT_HOOK_DEFAULT_PRIORITY_RESCAN_POLICY + PRIORITY_STEP,
|
||||
WP_EVENT_HOOK_DEFAULT_PRIORITY_RESCAN_DEFAULT_NODES = WP_EVENT_HOOK_DEFAULT_PRIORITY_AFTER_EVENTS_DEFAULT_NODES_STATE_SAVE + PRIORITY_STEP,
|
||||
|
||||
WP_EVENT_HOOK_DEFAULT_PRIORITY_NODE_ADDED = WP_EVENT_HOOK_DEFAULT_PRIORITY_RESCAN_POLICY + PRIORITY_JUMP,
|
||||
WP_EVENT_HOOK_DEFAULT_PRIORITY_NODE_ADDED_RESTORE_STREAM = WP_EVENT_HOOK_DEFAULT_PRIORITY_NODE_ADDED,
|
||||
@@ -120,6 +127,12 @@ WP_PRIVATE_API
|
||||
void wp_event_hook_set_dispatcher (WpEventHook * self,
|
||||
WpEventDispatcher * dispatcher);
|
||||
|
||||
WP_API
|
||||
void wp_event_hook_set_event (WpEventHook *self, WpEvent *event);
|
||||
|
||||
WP_API
|
||||
WpEvent *wp_event_hook_get_event (WpEventHook *self);
|
||||
|
||||
WP_API
|
||||
gboolean wp_event_hook_runs_for_event (WpEventHook * self, WpEvent * event);
|
||||
|
||||
|
@@ -12,6 +12,7 @@ typedef struct {
|
||||
WpBaseTestFixture base;
|
||||
WpObjectManager *om;
|
||||
GPtrArray *hooks_executed;
|
||||
GPtrArray *events;
|
||||
WpTransition *transition;
|
||||
} TestFixture;
|
||||
|
||||
@@ -20,6 +21,7 @@ test_events_setup (TestFixture *self, gconstpointer user_data)
|
||||
{
|
||||
wp_base_test_fixture_setup (&self->base, 0);
|
||||
self->hooks_executed = g_ptr_array_new ();
|
||||
self->events = g_ptr_array_new ();
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -35,6 +37,7 @@ test_events_teardown (TestFixture *self, gconstpointer user_data)
|
||||
{ \
|
||||
g_debug ("in hook_" #x); \
|
||||
g_ptr_array_add (self->hooks_executed, hook_##x); \
|
||||
g_ptr_array_add (self->events, event); \
|
||||
}
|
||||
|
||||
HOOK_FUNC(a)
|
||||
@@ -47,6 +50,7 @@ hook_quit (WpEvent * event, TestFixture * self)
|
||||
{
|
||||
g_debug ("in hook_quit");
|
||||
g_ptr_array_add (self->hooks_executed, hook_quit);
|
||||
g_ptr_array_add (self->events, event);
|
||||
g_main_loop_quit (self->base.loop);
|
||||
}
|
||||
|
||||
@@ -55,6 +59,7 @@ test_events_basic (TestFixture * self, gconstpointer user_data)
|
||||
{
|
||||
g_autoptr (WpEventDispatcher) dispatcher = NULL;
|
||||
g_autoptr (WpEventHook) hook = NULL;
|
||||
WpEvent *event1 = NULL, *event2 = NULL;
|
||||
|
||||
dispatcher = wp_event_dispatcher_get_instance (self->base.core);
|
||||
g_assert_nonnull (dispatcher);
|
||||
@@ -101,37 +106,73 @@ test_events_basic (TestFixture * self, gconstpointer user_data)
|
||||
wp_event_dispatcher_register_hook (dispatcher, hook);
|
||||
g_clear_object (&hook);
|
||||
|
||||
/* first event */
|
||||
wp_event_dispatcher_push_event (dispatcher,
|
||||
wp_event_new ("type1", 10, NULL, NULL, NULL));
|
||||
/* first event run */
|
||||
event1 = wp_event_new ("type1", 10, NULL, NULL, NULL);
|
||||
wp_event_dispatcher_push_event (dispatcher, event1);
|
||||
|
||||
g_assert_cmpint (self->hooks_executed->len, ==, 0);
|
||||
g_main_loop_run (self->base.loop);
|
||||
g_assert_cmpint (self->hooks_executed->len, ==, 4);
|
||||
g_assert (hook_c == self->hooks_executed->pdata[0]);
|
||||
g_assert (event1 == self->events->pdata[0]);
|
||||
g_assert (hook_a == self->hooks_executed->pdata[1]);
|
||||
g_assert (event1 == self->events->pdata [1]);
|
||||
g_assert (hook_b == self->hooks_executed->pdata [2]);
|
||||
g_assert (event1 == self->events->pdata [2]);
|
||||
g_assert (hook_quit == self->hooks_executed->pdata [3]);
|
||||
g_assert (event1 == self->events->pdata [3]);
|
||||
|
||||
g_ptr_array_remove_range (self->hooks_executed, 0, self->hooks_executed->len);
|
||||
g_assert_cmpint (self->hooks_executed->len, ==, 0);
|
||||
g_ptr_array_remove_range (self->events, 0, self->events->len);
|
||||
g_assert_cmpint (self->events->len, == , 0);
|
||||
|
||||
/* second event */
|
||||
wp_event_dispatcher_push_event (dispatcher,
|
||||
wp_event_new ("type1", 10,
|
||||
wp_properties_new ("test.prop", "some-val", NULL), NULL, NULL));
|
||||
wp_event_dispatcher_push_event (dispatcher,
|
||||
wp_event_new ("type2", 100,
|
||||
wp_properties_new ("test.prop", "some-val", NULL), NULL, NULL));
|
||||
/* second event run */
|
||||
event1 = wp_event_new ("type1", 10,
|
||||
wp_properties_new ("test.prop", "some-val", NULL), NULL, NULL);
|
||||
event2 = wp_event_new ("type2", 100,
|
||||
wp_properties_new ("test.prop", "some-val", NULL), NULL, NULL);
|
||||
|
||||
wp_event_dispatcher_push_event (dispatcher, event1);
|
||||
wp_event_dispatcher_push_event (dispatcher, event2);
|
||||
|
||||
g_assert_cmpint (self->hooks_executed->len, ==, 0);
|
||||
g_main_loop_run (self->base.loop);
|
||||
g_assert_cmpint (self->hooks_executed->len, ==, 5);
|
||||
g_assert (hook_d == self->hooks_executed->pdata [0]);
|
||||
g_assert (event2 == self->events->pdata [0]);
|
||||
g_assert (hook_c == self->hooks_executed->pdata [1]);
|
||||
g_assert (event1 == self->events->pdata [1]);
|
||||
g_assert (hook_a == self->hooks_executed->pdata [2]);
|
||||
g_assert (event1 == self->events->pdata [2]);
|
||||
g_assert (hook_b == self->hooks_executed->pdata [3]);
|
||||
g_assert (event1 == self->events->pdata [3]);
|
||||
g_assert (hook_quit == self->hooks_executed->pdata [4]);
|
||||
g_assert (event1 == self->events->pdata [4]);
|
||||
|
||||
g_ptr_array_remove_range (self->hooks_executed, 0, self->hooks_executed->len);
|
||||
g_assert_cmpint (self->hooks_executed->len, == , 0);
|
||||
g_ptr_array_remove_range (self->events, 0, self->events->len);
|
||||
g_assert_cmpint (self->events->len, == , 0);
|
||||
|
||||
|
||||
/* thrid event run to test event cancellation */
|
||||
event1 = wp_event_new ("type1", 10,
|
||||
wp_properties_new ("test.prop", "some-val", NULL), NULL, NULL);
|
||||
event2 = wp_event_new ("type2", 100,
|
||||
wp_properties_new ("test.prop", "some-val", NULL), NULL, NULL);
|
||||
|
||||
wp_event_dispatcher_push_event (dispatcher, event2);
|
||||
wp_event_dispatcher_push_event (dispatcher, event1);
|
||||
wp_event_stop_processing (event1);
|
||||
|
||||
g_assert_cmpint (self->hooks_executed->len, == , 0);
|
||||
g_main_loop_run (self->base.loop);
|
||||
g_assert_cmpint (self->hooks_executed->len, == , 2);
|
||||
g_assert (hook_d == self->hooks_executed->pdata [0]);
|
||||
g_assert (event2 == self->events->pdata [0]);
|
||||
g_assert (hook_quit == self->hooks_executed->pdata [1]);
|
||||
g_assert (event2 == self->events->pdata [1]);
|
||||
}
|
||||
|
||||
enum {
|
||||
|
Reference in New Issue
Block a user