protocol: add ei_connection.invalid_object

This event is to notify the client that an object used in a request was
unknown. This allows the client to work around race conditions like
binding to a seat that was removed.

This is currently the server-side only which is probably enough for now.
The only client-side created objects we have are the callbacks.
This commit is contained in:
Peter Hutterer 2023-02-10 14:48:00 +10:00
parent f6cfe9803c
commit 8c85b8fc1f
4 changed files with 30 additions and 1 deletions

View file

@ -337,6 +337,17 @@
<arg name="seat" type="new_id" interface="ei_seat"/>
<arg name="version" type="uint" summary="the interface version"/>
</event>
<event name="invalid_object" since="1">
<description summary="Invalid object in request notification">
Notification that an object ID used in a prior request was
invalid and does not exist.
This event is sent by the EIS implementation when an object that
does not exist as seen by the EIS implementation.
</description>
<arg name="invalid_id" type="uint" />
</event>
</interface>
<interface name="ei_callback" version="1">

View file

@ -291,6 +291,10 @@ brei_dispatch(struct brei_context *brei,
/* Find the object, it is stored in the ei/eis context */
struct brei_object *object = NULL;
rc = lookup_object(object_id, &object, user_data);
if (rc == -ENOENT) {
iobuf_pop(buf, msglen);
continue;
}
if (rc < 0)
goto error;

View file

@ -647,7 +647,8 @@ ei_connected(struct ei *ei)
}
}
static int handle_msg_disconnected(struct ei_connection *connection, uint32_t reason, const char *explanation)
static int
handle_msg_disconnected(struct ei_connection *connection, uint32_t reason, const char *explanation)
{
struct ei *ei = ei_connection_get_context(connection);
@ -659,6 +660,16 @@ static int handle_msg_disconnected(struct ei_connection *connection, uint32_t re
return -ECANCELED;
}
static int
handle_msg_invalid_object(struct ei_connection *connection, uint32_t object)
{
struct ei *ei = ei_connection_get_context(connection);
log_bug(ei, "Invalid object %#x, I don't yet know how to handle that", object);
return 0;
}
#define DISCONNECT_IF_SENDER_CONTEXT(ei_) do {\
if (ei_->is_sender) { \
log_bug_client(ei_, "Invalid event from receiver EIS context. Disconnecting"); \
@ -669,6 +680,7 @@ static int handle_msg_disconnected(struct ei_connection *connection, uint32_t re
static const struct ei_connection_interface interface = {
.disconnected = handle_msg_disconnected,
.seat = handle_msg_seat,
.invalid_object = handle_msg_invalid_object,
};
const struct ei_connection_interface *

View file

@ -321,6 +321,8 @@ lookup_object(uint32_t object_id, struct brei_object **object, void *userdata)
}
log_debug(eis_client_get_context(client), "Failed to find object %#x", object_id);
if (client->connection)
eis_connection_event_invalid_object(client->connection, object_id);
return -ENOENT;
}