ei: add EI_EVENT_SYNC as opaque event to correctly schedule callbacks

See the corresponding eis commit for details.

Part-of: <https://gitlab.freedesktop.org/libinput/libei/-/merge_requests/316>
This commit is contained in:
Peter Hutterer 2024-12-10 14:49:16 +10:00 committed by Marge Bot
parent 73e0e8d339
commit 564f14a739
12 changed files with 92 additions and 2 deletions

View file

@ -50,6 +50,7 @@ ei_event_type_to_string(enum ei_event_type type)
CASE_RETURN_STRING(EI_EVENT_DEVICE_RESUMED);
CASE_RETURN_STRING(EI_EVENT_KEYBOARD_MODIFIERS);
CASE_RETURN_STRING(EI_EVENT_PONG);
CASE_RETURN_STRING(EI_EVENT_SYNC);
CASE_RETURN_STRING(EI_EVENT_FRAME);
CASE_RETURN_STRING(EI_EVENT_DEVICE_START_EMULATING);
CASE_RETURN_STRING(EI_EVENT_DEVICE_STOP_EMULATING);
@ -100,6 +101,9 @@ ei_event_destroy(struct ei_event *event)
case EI_EVENT_PONG:
ei_ping_unref(event->pong.ping);
break;
case EI_EVENT_SYNC:
ei_pingpong_unref(event->sync.pingpong);
break;
}
ei_device_unref(event->device);
ei_seat_unref(event->seat);

View file

@ -72,6 +72,9 @@ struct ei_event {
struct {
struct ei_ping *ping;
} pong;
struct {
struct ei_pingpong *pingpong;
} sync;
};
};

View file

@ -171,6 +171,9 @@ ei_queue_disconnect_event(struct ei *ei);
void
ei_queue_pong_event(struct ei *ei, struct ei_ping *ping);
void
ei_queue_sync_event(struct ei *ei, struct ei_pingpong *ping);
void
ei_queue_device_removed_event(struct ei_device *device);

View file

@ -336,6 +336,16 @@ ei_queue_pong_event(struct ei *ei, struct ei_ping *ping)
queue_event(ei, e);
}
void
ei_queue_sync_event(struct ei *ei, struct ei_pingpong *ping)
{
struct ei_event *e = ei_event_new(ei);
e->type = EI_EVENT_SYNC;
e->sync.pingpong = ei_pingpong_ref(ping);
queue_event(ei, e);
}
void
ei_queue_seat_added_event(struct ei_seat *seat)
{
@ -683,6 +693,16 @@ ei_get_event(struct ei *ei)
struct ei_event *e = list_first_entry(&ei->event_queue, e, link);
list_remove(&e->link);
if (e->type == EI_EVENT_SYNC) {
_unref_(ei_pingpong) *pp = steal(&e->sync.pingpong);
log_debug(ei_event_get_context(e),
"object %#" PRIx64 ": ping pong done",
ei_pingpong_get_id(pp));
if (ei->state < EI_STATE_DISCONNECTED)
ei_pingpong_request_done(pp, 0);
}
return e;
}
@ -764,8 +784,7 @@ handle_msg_ping(struct ei_connection *connection, object_id_t id, uint32_t vers
DISCONNECT_IF_INVALID_VERSION(ei, ei_pingpong, id, version);
_unref_(ei_pingpong) *pingpong = ei_pingpong_new_for_id(ei, id, version);
ei_pingpong_request_done(pingpong, 0);
ei_queue_sync_event(ei_connection_get_context(connection), pingpong);
return NULL;
}

View file

@ -431,6 +431,17 @@ enum ei_event_type {
*/
EI_EVENT_PONG = 90,
/**
* This event represents a synchronization request (ping) from the EIS
* implementation. The corresponding reply (pong) will be sent when
* it is unref'd. It has no other API.
*
* The caller must ensure that any state changes triggered by messages
* received prior to this event have been resolved and communicated to the
* EIS implementation prior to calling ei_event_unref().
*/
EI_EVENT_SYNC,
/**
* "Hardware" frame event. This event **must** be sent by the server
* and notifies the client that the previous set of events belong to

View file

@ -502,6 +502,7 @@ new_context(enum peck_ei_mode ei_mode)
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTOSEAT);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTOSTART);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_FRAME);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_SYNC);
peck_ei_enable_fatal_bug(peck);
peck_eis_enable_fatal_bug(peck);
@ -655,6 +656,7 @@ peck_enable_ei_behavior(struct peck *peck, enum peck_ei_behavior behavior)
case PECK_EI_BEHAVIOR_HANDLE_ADDED_BUTTON:
case PECK_EI_BEHAVIOR_HANDLE_ADDED_SCROLL:
case PECK_EI_BEHAVIOR_HANDLE_FRAME:
case PECK_EI_BEHAVIOR_HANDLE_SYNC:
flag_set(peck->ei_behavior, behavior);
break;
case PECK_EI_BEHAVIOR_HANDLE_RESUMED:
@ -1076,6 +1078,10 @@ _peck_dispatch_ei(struct peck *peck, int lineno)
break;
case EI_EVENT_PONG:
break;
case EI_EVENT_SYNC:
if (flag_is_set(peck->ei_behavior, PECK_EI_BEHAVIOR_HANDLE_SYNC))
process_event = tristate_yes;
break;
case EI_EVENT_FRAME:
/* Ensure we only expect frames when we expect them */
munit_assert_true(need_frame);
@ -1247,6 +1253,12 @@ _peck_assert_no_ei_events(struct ei *ei, int lineno)
continue;
}
if (peck && flag_is_set(peck->ei_behavior, PECK_EI_BEHAVIOR_HANDLE_SYNC) &&
ei_event_get_type(e) == EI_EVENT_SYNC) {
log_debug(peck, "Skipping over sync event\n");
continue;
}
munit_errorf("Expected empty event queue, have: %s, line %d\n",
peck_ei_event_name(e), lineno);
}
@ -1295,6 +1307,14 @@ _peck_ei_next_event(struct ei *ei, enum ei_event_type type, int lineno)
}
}
if (flag_is_set(peck->ei_behavior, PECK_EI_BEHAVIOR_HANDLE_SYNC)) {
while (event && ei_event_get_type(event) == EI_EVENT_SYNC) {
ei_event_unref(event);
log_debug(peck, "Skipping over sync event\n");
event = ei_get_event(ei);
}
}
if (!event)
munit_errorf("Expected ei event type %s, got none, line %d\n",
peck_ei_event_type_name(type),
@ -1406,6 +1426,7 @@ peck_ei_event_type_name(enum ei_event_type type)
CASE_STRING(DEVICE_RESUMED);
CASE_STRING(KEYBOARD_MODIFIERS);
CASE_STRING(PONG);
CASE_STRING(SYNC);
CASE_STRING(FRAME);
CASE_STRING(DEVICE_START_EMULATING);
CASE_STRING(DEVICE_STOP_EMULATING);

View file

@ -139,6 +139,10 @@ enum peck_ei_behavior {
* Handle frame events. This behavior is enabled by default.
*/
PECK_EI_BEHAVIOR_HANDLE_FRAME,
/**
* Handle sync events. This behavior is enabled by default.
*/
PECK_EI_BEHAVIOR_HANDLE_SYNC,
};
struct peck;

View file

@ -295,6 +295,7 @@ MUNIT_TEST(test_ei_device_close)
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_DEFAULT_SEAT);
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_DEVICES);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_SYNC);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTODEVICES);
peck_dispatch_until_stable(peck);
@ -1873,6 +1874,7 @@ MUNIT_TEST(test_passive_ei_device_start_stop_emulating)
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_RESUME_DEVICE);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_SYNC);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_CONNECT);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTOSEAT);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_ADDED_POINTER);
@ -1914,6 +1916,7 @@ MUNIT_TEST(test_passive_ei_device_stop_emulating_when_removing)
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_RESUME_DEVICE);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_SYNC);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_CONNECT);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTOSEAT);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_ADDED_POINTER);
@ -2901,6 +2904,7 @@ MUNIT_TEST(test_passive_ei_frame_timestamp)
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_RESUME_DEVICE);
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_KEYBOARD);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_SYNC);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_CONNECT);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTODEVICES);
peck_dispatch_until_stable(peck);
@ -2960,6 +2964,7 @@ MUNIT_TEST(test_passive_ei_flush_frame)
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_RESUME_DEVICE);
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_KEYBOARD);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_SYNC);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_CONNECT);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTODEVICES);
peck_dispatch_until_stable(peck);

View file

@ -38,6 +38,7 @@ MUNIT_TEST(test_ei_seat_bind_unbind)
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_POINTER);
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_KEYBOARD);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_SYNC);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_CONNECT);
peck_dispatch_until_stable(peck);
@ -95,6 +96,7 @@ MUNIT_TEST(test_ei_seat_bind_unbind_noref)
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_POINTER);
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_KEYBOARD);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_SYNC);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_CONNECT);
peck_dispatch_until_stable(peck);
@ -144,6 +146,7 @@ MUNIT_TEST(test_ei_seat_bind_unbind_immediately)
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_POINTER);
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ADD_KEYBOARD);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_SYNC);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_CONNECT);
peck_dispatch_until_stable(peck);

View file

@ -126,6 +126,7 @@ MUNIT_TEST(test_ei_disconnect_after_connect)
_unref_(eis_client) *client = NULL;
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_SYNC);
peck_dispatch_until_stable(peck);
@ -212,6 +213,7 @@ MUNIT_TEST(test_ei_disconnect_after_seat)
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT);
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_DEFAULT_SEAT);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_SYNC);
peck_dispatch_until_stable(peck);
@ -246,6 +248,7 @@ MUNIT_TEST(test_ei_disconnect_self_after_seat)
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT);
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_DEFAULT_SEAT);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_SYNC);
peck_dispatch_until_stable(peck);
@ -283,6 +286,7 @@ MUNIT_TEST(test_ei_disconnect_after_bind_before_received)
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT);
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_DEFAULT_SEAT);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_SYNC);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_CONNECT);
peck_dispatch_until_stable(peck);
@ -317,6 +321,7 @@ MUNIT_TEST(test_ei_disconnect_self_after_bind_before_received)
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT);
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_DEFAULT_SEAT);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_SYNC);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_CONNECT);
peck_dispatch_until_stable(peck);
@ -355,6 +360,7 @@ MUNIT_TEST(test_ei_disconnect_after_bind_after_received)
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT);
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_DEFAULT_SEAT);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_SYNC);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_CONNECT);
peck_dispatch_until_stable(peck);
@ -391,6 +397,7 @@ MUNIT_TEST(test_ei_disconnect_self_after_bind_after_received)
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT);
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_DEFAULT_SEAT);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_SYNC);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_CONNECT);
peck_dispatch_until_stable(peck);
@ -432,6 +439,7 @@ MUNIT_TEST(test_ei_disconnect_after_unbind_before_received)
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_ALL);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_SYNC);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_CONNECT);
peck_dispatch_until_stable(peck);
@ -477,6 +485,7 @@ MUNIT_TEST(test_ei_disconnect_after_unbind_after_received)
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_ALL);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_SYNC);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_CONNECT);
peck_dispatch_until_stable(peck);
@ -520,6 +529,7 @@ MUNIT_TEST(test_client_is_sender)
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_NONE);
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_HANDLE_SYNC);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_SYNC);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_CONNECT);
peck_dispatch_until_stable(peck);
@ -539,6 +549,7 @@ MUNIT_TEST(test_client_is_receiver)
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_NONE);
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_HANDLE_SYNC);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_SYNC);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_CONNECT);
peck_dispatch_until_stable(peck);
@ -922,6 +933,7 @@ MUNIT_TEST(test_ei_ping_within_frame)
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_RESUME_DEVICE);
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_HANDLE_SYNC);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_SYNC);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTODEVICES);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_AUTOSTART);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_ADDED);

View file

@ -53,6 +53,7 @@ MUNIT_TEST(eistest_name)
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_NONE);
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_HANDLE_SYNC);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_SYNC);
/* The name is set by peck_new() and immutable after the
* backend was set, which peck_new() does for us as well.
@ -85,6 +86,7 @@ MUNIT_TEST(eistest_cliend_bind_all_caps)
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT);
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_DEFAULT_SEAT);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_SYNC);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_CONNECT);
peck_dispatch_until_stable(peck);
@ -122,6 +124,7 @@ MUNIT_TEST(eistest_cliend_bind_some_caps)
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT);
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_DEFAULT_SEAT);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_NONE);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_SYNC);
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_CONNECT);
peck_dispatch_until_stable(peck);

View file

@ -455,6 +455,8 @@ int main(int argc, char **argv)
case EI_EVENT_PONG:
print_pong_event(e);
break;
case EI_EVENT_SYNC:
break;
}
}
}