static void marshal_demarshal(struct marshal_data *data, void (*func)(void), int size, const char *format, ...) { struct wl_closure *closure; static const int opcode = 4444; static struct wl_object sender = { NULL, NULL, 1234 }; struct wl_message message = { "test", format, NULL }; struct wl_map objects; struct wl_object object = { NULL, &func, 0 }; va_list ap; uint32_t msg[1] = { 1234 }; va_start(ap, format); closure = wl_closure_vmarshal(&sender, opcode, ap, &message); va_end(ap); assert(closure); assert(wl_closure_send(closure, data->write_connection) == 0); wl_closure_destroy(closure); assert(wl_connection_flush(data->write_connection) == size); assert(wl_connection_read(data->read_connection) == size); wl_map_init(&objects, WL_MAP_SERVER_SIDE); object.id = msg[0]; closure = wl_connection_demarshal(data->read_connection, size, &objects, &message); assert(closure); wl_closure_invoke(closure, WL_CLOSURE_INVOKE_SERVER, &object, 0, data); wl_closure_destroy(closure); }
static int read_events(struct wl_display *display) { int total, rem, size; uint32_t serial; display->reader_count--; if (display->reader_count == 0) { total = wl_connection_read(display->connection); if (total == -1) { if (errno == EAGAIN) return 0; display_fatal_error(display, errno); return -1; } else if (total == 0) { /* The compositor has closed the socket. This * should be considered an error so we'll fake * an errno */ errno = EPIPE; display_fatal_error(display, errno); return -1; } for (rem = total; rem >= 8; rem -= size) { size = queue_event(display, rem); if (size == -1) { display_fatal_error(display, errno); return -1; } else if (size == 0) { break; } } display->read_serial++; pthread_cond_broadcast(&display->reader_cond); } else { serial = display->read_serial; while (display->read_serial == serial) pthread_cond_wait(&display->reader_cond, &display->mutex); } return 0; }
static void expected_fail_demarshal(struct marshal_data *data, const char *format, const uint32_t *msg, int expected_error) { struct wl_message message = { "test", format, NULL }; struct wl_closure *closure; struct wl_map objects; int size = (msg[1] >> 16); assert(write(data->s[1], msg, size) == size); assert(wl_connection_read(data->read_connection) == size); wl_map_init(&objects, WL_MAP_SERVER_SIDE); closure = wl_connection_demarshal(data->read_connection, size, &objects, &message); assert(closure == NULL); assert(errno == expected_error); }
static void demarshal(struct marshal_data *data, const char *format, uint32_t *msg, void (*func)(void)) { struct wl_message message = { "test", format, NULL }; struct wl_closure *closure; struct wl_map objects; struct wl_object object = { NULL, &func, 0 }; int size = msg[1]; assert(write(data->s[1], msg, size) == size); assert(wl_connection_read(data->read_connection) == size); wl_map_init(&objects, WL_MAP_SERVER_SIDE); object.id = msg[0]; closure = wl_connection_demarshal(data->read_connection, size, &objects, &message); assert(closure); wl_closure_invoke(closure, WL_CLOSURE_INVOKE_SERVER, &object, 0, data); wl_closure_destroy(closure); }