void *data;
wl_connection_update_func_t update;
struct wl_closure receive_closure, send_closure;
+ int write_signalled;
};
union wl_value {
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) {
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
}
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)
{
union wl_value *value;
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);
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;
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, ...)
{
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);
}
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);