Commit 4abc56bd authored by Kristian Høgsberg's avatar Kristian Høgsberg
Browse files

Introduce wl_resource_queue_event() for sending events later

Some events, such as the display.delete_id, aren't very urgent and we
would like to not always send them immdiately and cause an unnecessary
context switch.  The wl_resource_queue_event() function will place the
event in the connection output buffer but not request the main loop to
poll for writable.  The effect is that the event will just sit in the
output buffer until a more important event comes around and requires
flushing.
parent 3a1e6df3
......@@ -65,6 +65,7 @@ struct wl_connection {
void *data;
wl_connection_update_func_t update;
struct wl_closure receive_closure, send_closure;
int write_signalled;
};
union wl_value {
......@@ -285,10 +286,13 @@ wl_connection_data(struct wl_connection *connection, uint32_t mask)
close_fds(&connection->fds_out);
connection->out.tail += len;
if (connection->out.tail == connection->out.head)
if (connection->out.tail == connection->out.head &&
connection->write_signalled) {
connection->update(connection,
WL_CONNECTION_READABLE,
connection->data);
connection->write_signalled = 0;
}
}
if (mask & WL_CONNECTION_READABLE) {
......@@ -334,11 +338,24 @@ wl_connection_write(struct wl_connection *connection,
wl_buffer_put(&connection->out, data, count);
if (connection->out.head - connection->out.tail == count)
if (!connection->write_signalled) {
connection->update(connection,
WL_CONNECTION_READABLE |
WL_CONNECTION_WRITABLE,
connection->data);
connection->write_signalled = 1;
}
}
static void
wl_connection_queue(struct wl_connection *connection,
const void *data, size_t count)
{
if (connection->out.head - connection->out.tail +
count > ARRAY_LENGTH(connection->out.data))
wl_connection_data(connection, WL_CONNECTION_WRITABLE);
wl_buffer_put(&connection->out, data, count);
}
static int
......@@ -703,6 +720,15 @@ wl_closure_send(struct wl_closure *closure, struct wl_connection *connection)
wl_connection_write(connection, closure->start, size);
}
void
wl_closure_queue(struct wl_closure *closure, struct wl_connection *connection)
{
uint32_t size;
size = closure->start[1] >> 16;
wl_connection_queue(connection, closure->start, size);
}
void
wl_closure_print(struct wl_closure *closure, struct wl_object *target, int send)
{
......
......@@ -61,6 +61,8 @@ wl_closure_invoke(struct wl_closure *closure,
void
wl_closure_send(struct wl_closure *closure, struct wl_connection *connection);
void
wl_closure_queue(struct wl_closure *closure, struct wl_connection *connection);
void
wl_closure_print(struct wl_closure *closure, struct wl_object *target, int send);
void
wl_closure_destroy(struct wl_closure *closure);
......
......@@ -469,10 +469,6 @@ wl_display_iterate(struct wl_display *display, uint32_t mask)
len = wl_connection_data(display->connection, mask);
if (wl_debug && (mask & WL_DISPLAY_READABLE))
fprintf(stderr,
"[-----------] wakeup, read %d bytes\n", len);
while (len > 0) {
if (len < sizeof p)
break;
......
......@@ -108,6 +108,28 @@ wl_resource_post_event(struct wl_resource *resource, uint32_t opcode, ...)
wl_closure_destroy(closure);
}
WL_EXPORT void
wl_resource_queue_event(struct wl_resource *resource, uint32_t opcode, ...)
{
struct wl_closure *closure;
struct wl_object *object = &resource->object;
va_list ap;
va_start(ap, opcode);
closure = wl_connection_vmarshal(resource->client->connection,
object, opcode, ap,
&object->interface->events[opcode]);
va_end(ap);
wl_closure_queue(closure, resource->client->connection);
if (wl_debug)
wl_closure_print(closure, object, true);
wl_closure_destroy(closure);
}
WL_EXPORT void
wl_resource_post_error(struct wl_resource *resource,
uint32_t code, const char *msg, ...)
......@@ -314,8 +336,8 @@ wl_resource_destroy(struct wl_resource *resource, uint32_t time)
{
struct wl_client *client = resource->client;
wl_resource_post_event(resource->client->display_resource,
WL_DISPLAY_DELETE_ID, resource->object.id);
wl_resource_queue_event(resource->client->display_resource,
WL_DISPLAY_DELETE_ID, resource->object.id);
wl_map_insert_at(&client->objects, resource->object.id, NULL);
destroy_resource(resource, &time);
}
......
......@@ -216,6 +216,8 @@ struct wl_selection {
void wl_resource_post_event(struct wl_resource *resource,
uint32_t opcode, ...);
void wl_resource_queue_event(struct wl_resource *resource,
uint32_t opcode, ...);
void wl_resource_post_error(struct wl_resource *resource,
uint32_t code, const char *msg, ...);
void wl_resource_post_no_memory(struct wl_resource *resource);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment