From 223d1f32861e21bf9827b813659fbe46c97d8e66 Mon Sep 17 00:00:00 2001 From: Erik Chen Date: Thu, 20 Oct 2022 00:06:01 +0000 Subject: [PATCH 1/5] Apply WIP CL from upstream wayland This CL provides the capability of dynamically modifying the buffer size. https://gitlab.freedesktop.org/wayland/wayland/-/commit/0bfcd4c4bef0ddb555c0e9f07cd3ceff81a33313 Note that I am not the author. This CL has been reviewed upstream. Bug: 1342356 Change-Id: I24f90fb31248a52aa97f1813a5ff9b30157aa350 Upstream-Status: Pending --- src/connection.c | 303 ++++++++++++++++++++++++++++---------- src/wayland-client.c | 2 +- src/wayland-private.h | 8 +- src/wayland-server-core.h | 7 + src/wayland-server.c | 63 +++++++- tests/connection-test.c | 46 +++++- tests/display-test.c | 5 +- tests/os-wrappers-test.c | 6 +- 8 files changed, 350 insertions(+), 90 deletions(-) diff --git a/src/connection.c b/src/connection.c index ceaeac1..bc6d730 100644 --- a/src/connection.c +++ b/src/connection.c @@ -55,12 +55,12 @@ div_roundup(uint32_t n, size_t a) } struct wl_ring_buffer { - char data[4096]; - uint32_t head, tail; + char *data; + size_t head, tail; + uint32_t size_bits; + uint32_t max_size_bits; /* 0 for unlimited */ }; -#define MASK(i) ((i) & 4095) - #define MAX_FDS_OUT 28 #define CLEN (CMSG_LEN(MAX_FDS_OUT * sizeof(int32_t))) @@ -71,23 +71,27 @@ struct wl_connection { int want_flush; }; +static size_t +ring_buffer_space(const struct wl_ring_buffer *b) { + return ((size_t)1) << b->size_bits; +} + +static size_t +ring_buffer_mask(const struct wl_ring_buffer *b, size_t i) { + size_t m = (((size_t)1) << b->size_bits) - 1; + return i & m; +} + static int ring_buffer_put(struct wl_ring_buffer *b, const void *data, size_t count) { - uint32_t head, size; + size_t head, size; - if (count > sizeof(b->data)) { - wl_log("Data too big for buffer (%d > %d).\n", - count, sizeof(b->data)); - errno = E2BIG; - return -1; - } - - head = MASK(b->head); - if (head + count <= sizeof b->data) { + head = ring_buffer_mask(b, b->head); + if (head + count <= ring_buffer_space(b)) { memcpy(b->data + head, data, count); } else { - size = sizeof b->data - head; + size = ring_buffer_space(b) - head; memcpy(b->data + head, data, size); memcpy(b->data, (const char *) data + size, count - size); } @@ -100,21 +104,21 @@ ring_buffer_put(struct wl_ring_buffer *b, const void *data, size_t count) static void ring_buffer_put_iov(struct wl_ring_buffer *b, struct iovec *iov, int *count) { - uint32_t head, tail; + size_t head, tail; - head = MASK(b->head); - tail = MASK(b->tail); + head = ring_buffer_mask(b, b->head); + tail = ring_buffer_mask(b, b->tail); if (head < tail) { iov[0].iov_base = b->data + head; iov[0].iov_len = tail - head; *count = 1; } else if (tail == 0) { iov[0].iov_base = b->data + head; - iov[0].iov_len = sizeof b->data - head; + iov[0].iov_len = ring_buffer_space(b) - head; *count = 1; } else { iov[0].iov_base = b->data + head; - iov[0].iov_len = sizeof b->data - head; + iov[0].iov_len = ring_buffer_space(b) - head; iov[1].iov_base = b->data; iov[1].iov_len = tail; *count = 2; @@ -124,21 +128,21 @@ ring_buffer_put_iov(struct wl_ring_buffer *b, struct iovec *iov, int *count) static void ring_buffer_get_iov(struct wl_ring_buffer *b, struct iovec *iov, int *count) { - uint32_t head, tail; + size_t head, tail; - head = MASK(b->head); - tail = MASK(b->tail); + head = ring_buffer_mask(b, b->head); + tail = ring_buffer_mask(b, b->tail); if (tail < head) { iov[0].iov_base = b->data + tail; iov[0].iov_len = head - tail; *count = 1; } else if (head == 0) { iov[0].iov_base = b->data + tail; - iov[0].iov_len = sizeof b->data - tail; + iov[0].iov_len = ring_buffer_space(b) - tail; *count = 1; } else { iov[0].iov_base = b->data + tail; - iov[0].iov_len = sizeof b->data - tail; + iov[0].iov_len = ring_buffer_space(b) - tail; iov[1].iov_base = b->data; iov[1].iov_len = head; *count = 2; @@ -148,26 +152,136 @@ ring_buffer_get_iov(struct wl_ring_buffer *b, struct iovec *iov, int *count) static void ring_buffer_copy(struct wl_ring_buffer *b, void *data, size_t count) { - uint32_t tail, size; + size_t tail, size; - tail = MASK(b->tail); - if (tail + count <= sizeof b->data) { + tail = ring_buffer_mask(b, b->tail); + if (tail + count <= ring_buffer_space(b)) { memcpy(data, b->data + tail, count); } else { - size = sizeof b->data - tail; + size = ring_buffer_space(b) - tail; memcpy(data, b->data + tail, size); memcpy((char *) data + size, b->data, count - size); } } -static uint32_t +static size_t ring_buffer_size(struct wl_ring_buffer *b) { return b->head - b->tail; } +static uint32_t +get_max_size_bits_for_size(size_t buffer_size) +{ + uint32_t max_size_bits = WL_BUFFER_DEFAULT_SIZE_POT; + + /* buffer_size == 0 means unbound buffer size */ + if (buffer_size == 0) + return 0; + + do { + if (buffer_size <= (((size_t)1) << max_size_bits)) + break; + } while (max_size_bits++ < (8 * sizeof(size_t) - 1)); + + return max_size_bits; +} + +static int +ring_buffer_allocate(struct wl_ring_buffer *b, size_t size_bits) +{ + char *new_data; + + new_data = calloc(((size_t)1) << size_bits, 1); + if (!new_data) { + errno = ENOMEM; + return -1; + } + + ring_buffer_copy(b, new_data, ring_buffer_size(b)); + free(b->data); + b->data = new_data; + b->size_bits = size_bits; + b->head = ring_buffer_size(b); + b->tail = 0; + + return 0; +} + +static size_t +ring_buffer_get_bits_for_size(struct wl_ring_buffer *b, size_t count) +{ + size_t net_size = ring_buffer_size(b) + count; + size_t max_size_bits = get_max_size_bits_for_size(net_size); + + if (max_size_bits < WL_BUFFER_DEFAULT_SIZE_POT) + max_size_bits = WL_BUFFER_DEFAULT_SIZE_POT; + + if (b->max_size_bits > 0 && max_size_bits > b->max_size_bits) + max_size_bits = b->max_size_bits; + + return max_size_bits; +} + +static int +ring_buffer_check_space(struct wl_ring_buffer *b, size_t count) +{ + if (ring_buffer_size(b) + count > ring_buffer_space(b)) { + wl_log("Data too big for buffer (%d + %zd > %zd).\n", + ring_buffer_size(b), count, ring_buffer_space(b)); + errno = E2BIG; + return -1; + } + + return 0; +} + +static int +ring_buffer_ensure_space(struct wl_ring_buffer *b, size_t count) +{ + size_t size_bits = ring_buffer_get_bits_for_size(b, count); + size_t net_size = ring_buffer_size(b) + count; + + if (b->data == NULL) + return ring_buffer_allocate(b, size_bits); + + /* Do not shrink (reallocate) if net size won't fit */ + if (net_size >= (((size_t)1) << size_bits) || b->size_bits == size_bits) + return ring_buffer_check_space(b, count); + + if (ring_buffer_allocate(b, size_bits) < 0) + return -1; + + return ring_buffer_check_space(b, count); +} + +void +wl_connection_set_max_buffer_size(struct wl_connection *connection, + size_t max_buffer_size) +{ + uint32_t max_size_bits; + + max_size_bits = get_max_size_bits_for_size(max_buffer_size); + + connection->fds_in.size_bits = WL_BUFFER_DEFAULT_SIZE_POT; + connection->fds_in.max_size_bits = max_size_bits; + ring_buffer_ensure_space(&connection->fds_in, 0); + + connection->fds_out.size_bits = WL_BUFFER_DEFAULT_SIZE_POT; + connection->fds_out.max_size_bits = max_size_bits; + ring_buffer_ensure_space(&connection->fds_out, 0); + + connection->in.size_bits = WL_BUFFER_DEFAULT_SIZE_POT; + connection->in.max_size_bits = max_size_bits; + ring_buffer_ensure_space(&connection->in, 0); + + connection->out.size_bits = WL_BUFFER_DEFAULT_SIZE_POT; + connection->out.max_size_bits = max_size_bits; + ring_buffer_ensure_space(&connection->out, 0); +} + struct wl_connection * -wl_connection_create(int fd) +wl_connection_create(int fd, size_t max_buffer_size) { struct wl_connection *connection; @@ -175,6 +289,8 @@ wl_connection_create(int fd) if (connection == NULL) return NULL; + wl_connection_set_max_buffer_size(connection, max_buffer_size); + connection->fd = fd; return connection; @@ -183,20 +299,28 @@ wl_connection_create(int fd) static void close_fds(struct wl_ring_buffer *buffer, int max) { - int32_t fds[sizeof(buffer->data) / sizeof(int32_t)], i, count; - size_t size; + size_t size, tail, space; + int32_t i, count, *p; size = ring_buffer_size(buffer); if (size == 0) return; - ring_buffer_copy(buffer, fds, size); - count = size / sizeof fds[0]; + count = size / sizeof(int32_t); if (max > 0 && max < count) count = max; - size = count * sizeof fds[0]; - for (i = 0; i < count; i++) - close(fds[i]); + + tail = ring_buffer_mask(buffer, buffer->tail); + space = ring_buffer_space(buffer); + + p = (int32_t *) (buffer->data + tail); + for (i = 0; i < count; i++) { + if (p >= (int32_t *) (buffer->data + space)) + p = (int32_t *) buffer->data; + close(*p++); + } + + size = count * sizeof(int32_t); buffer->tail += size; } @@ -213,6 +337,10 @@ wl_connection_destroy(struct wl_connection *connection) close_fds(&connection->fds_out, -1); close_fds(&connection->fds_in, -1); + free(connection->fds_in.data); + free(connection->fds_out.data); + free(connection->in.data); + free(connection->out.data); free(connection); return fd; @@ -256,7 +384,7 @@ static int decode_cmsg(struct wl_ring_buffer *buffer, struct msghdr *msg) { struct cmsghdr *cmsg; - size_t size, max, i; + size_t size, i; int overflow = 0; for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; @@ -266,8 +394,8 @@ decode_cmsg(struct wl_ring_buffer *buffer, struct msghdr *msg) continue; size = cmsg->cmsg_len - CMSG_LEN(0); - max = sizeof(buffer->data) - ring_buffer_size(buffer); - if (size > max || overflow) { + + if (ring_buffer_ensure_space(buffer, size) < 0 || overflow) { overflow = 1; size /= sizeof(int32_t); for (i = 0; i < size; i++) @@ -293,17 +421,30 @@ wl_connection_flush(struct wl_connection *connection) char cmsg[CLEN]; int len = 0, count; size_t clen; - uint32_t tail; + size_t tail; if (!connection->want_flush) return 0; tail = connection->out.tail; while (connection->out.head - connection->out.tail > 0) { - ring_buffer_get_iov(&connection->out, iov, &count); - build_cmsg(&connection->fds_out, cmsg, &clen); + if (clen >= CMSG_LEN(MAX_FDS_OUT * sizeof(int32_t))) { + /* Send only a single byte, to ensure all FDs are sent + * before the bytes are cleared out. This can fail to + * clear the FDs first if individual messages are allowed to + * have 8*28 = 224 fds. */ + iov[0].iov_base = connection->out.data + + ring_buffer_mask(&connection->out, connection->out.tail); + iov[0].iov_len = 1; + count = 1; + } else { + ring_buffer_get_iov(&connection->out, iov, &count); + } + + msg.msg_name = NULL; + msg.msg_namelen = 0; msg.msg_iov = iov; msg.msg_iovlen = count; msg.msg_control = (clen > 0) ? cmsg : NULL; @@ -341,49 +482,49 @@ wl_connection_read(struct wl_connection *connection) char cmsg[CLEN]; int len, count, ret; - if (ring_buffer_size(&connection->in) >= sizeof(connection->in.data)) { - errno = EOVERFLOW; - return -1; - } + while (1) { + int data_size = ring_buffer_size(&connection->in); + size_t size_bits = ring_buffer_get_bits_for_size(&connection->in, 1); - ring_buffer_put_iov(&connection->in, iov, &count); + // stop once we've read the max buffer size + if (data_size >= (1 << size_bits)) + return data_size; + if (ring_buffer_ensure_space(&connection->in, 1) < 0) + return -1; - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_iov = iov; - msg.msg_iovlen = count; - msg.msg_control = cmsg; - msg.msg_controllen = sizeof cmsg; - msg.msg_flags = 0; + ring_buffer_put_iov(&connection->in, iov, &count); - do { - len = wl_os_recvmsg_cloexec(connection->fd, &msg, MSG_DONTWAIT); - } while (len < 0 && errno == EINTR); + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = iov; + msg.msg_iovlen = count; + msg.msg_control = cmsg; + msg.msg_controllen = sizeof cmsg; + msg.msg_flags = 0; - if (len <= 0) - return len; + do { + len = wl_os_recvmsg_cloexec(connection->fd, &msg, MSG_DONTWAIT); + } while (len < 0 && errno == EINTR); - ret = decode_cmsg(&connection->fds_in, &msg); - if (ret) - return -1; + if (len < 0 && errno != EAGAIN) { + return -1; + } else if (len <= 0) { + return (data_size > 0) ? data_size : len; + } - connection->in.head += len; + ret = decode_cmsg(&connection->fds_in, &msg); + if (ret) + return -1; - return wl_connection_pending_input(connection); + connection->in.head += len; + } } int wl_connection_write(struct wl_connection *connection, const void *data, size_t count) { - if (connection->out.head - connection->out.tail + - count > ARRAY_LENGTH(connection->out.data)) { - connection->want_flush = 1; - if (wl_connection_flush(connection) < 0) - return -1; - } - - if (ring_buffer_put(&connection->out, data, count) < 0) + if (wl_connection_queue(connection, data, count) < 0) return -1; connection->want_flush = 1; @@ -396,12 +537,15 @@ 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)) { + count > WL_BUFFER_DEFAULT_MAX_SIZE) { connection->want_flush = 1; - if (wl_connection_flush(connection) < 0) + if (wl_connection_flush(connection) < 0 && errno != EAGAIN) return -1; } + if (ring_buffer_ensure_space(&connection->out, count) < 0) + return -1; + return ring_buffer_put(&connection->out, data, count); } @@ -427,12 +571,15 @@ wl_connection_get_fd(struct wl_connection *connection) static int wl_connection_put_fd(struct wl_connection *connection, int32_t fd) { - if (ring_buffer_size(&connection->fds_out) == MAX_FDS_OUT * sizeof fd) { + if (ring_buffer_size(&connection->fds_out) >= MAX_FDS_OUT * sizeof fd) { connection->want_flush = 1; - if (wl_connection_flush(connection) < 0) + if (wl_connection_flush(connection) < 0 && errno != EAGAIN) return -1; } + if (ring_buffer_ensure_space(&connection->fds_out, sizeof fd) < 0) + return -1; + return ring_buffer_put(&connection->fds_out, &fd, sizeof fd); } diff --git a/src/wayland-client.c b/src/wayland-client.c index b57bfe9..895d7b8 100644 --- a/src/wayland-client.c +++ b/src/wayland-client.c @@ -1198,7 +1198,7 @@ wl_display_connect_to_fd(int fd) */ display->proxy.version = 0; - display->connection = wl_connection_create(display->fd); + display->connection = wl_connection_create(display->fd, 0); if (display->connection == NULL) goto err_connection; diff --git a/src/wayland-private.h b/src/wayland-private.h index 9274f1b..a3a5032 100644 --- a/src/wayland-private.h +++ b/src/wayland-private.h @@ -47,6 +47,8 @@ #define WL_SERVER_ID_START 0xff000000 #define WL_MAP_MAX_OBJECTS 0x00f00000 #define WL_CLOSURE_MAX_ARGS 20 +#define WL_BUFFER_DEFAULT_SIZE_POT 12 +#define WL_BUFFER_DEFAULT_MAX_SIZE (1 << WL_BUFFER_DEFAULT_SIZE_POT) struct wl_object { const struct wl_interface *interface; @@ -106,7 +108,7 @@ void wl_map_for_each(struct wl_map *map, wl_iterator_func_t func, void *data); struct wl_connection * -wl_connection_create(int fd); +wl_connection_create(int fd, size_t max_buffer_size); int wl_connection_destroy(struct wl_connection *connection); @@ -237,4 +239,8 @@ zalloc(size_t s) void wl_connection_close_fds_in(struct wl_connection *connection, int max); +void +wl_connection_set_max_buffer_size(struct wl_connection *connection, + size_t max_buffer_size); + #endif diff --git a/src/wayland-server-core.h b/src/wayland-server-core.h index df95821..15ee498 100644 --- a/src/wayland-server-core.h +++ b/src/wayland-server-core.h @@ -217,6 +217,10 @@ wl_display_flush_clients(struct wl_display *display); void wl_display_destroy_clients(struct wl_display *display); +void +wl_display_set_default_max_buffer_size(struct wl_display *display, + size_t max_buffer_size); + struct wl_client; typedef void (*wl_global_bind_func_t)(struct wl_client *client, void *data, @@ -365,6 +369,9 @@ wl_client_for_each_resource(struct wl_client *client, wl_client_for_each_resource_iterator_func_t iterator, void *user_data); +void +wl_client_set_max_buffer_size(struct wl_client *client, size_t max_buffer_size); + /** \class wl_listener * * \brief A single listener for Wayland signals diff --git a/src/wayland-server.c b/src/wayland-server.c index d51acc6..166a065 100644 --- a/src/wayland-server.c +++ b/src/wayland-server.c @@ -110,6 +110,8 @@ struct wl_display { int terminate_efd; struct wl_event_source *term_source; + + size_t max_buffer_size; }; struct wl_global { @@ -538,7 +540,8 @@ wl_client_create(struct wl_display *display, int fd) &client->pid) != 0) goto err_source; - client->connection = wl_connection_create(fd); + client->connection = wl_connection_create(fd, display->max_buffer_size); + if (client->connection == NULL) goto err_source; @@ -1144,6 +1147,7 @@ wl_display_create(void) display->global_filter = NULL; display->global_filter_data = NULL; + display->max_buffer_size = WL_BUFFER_DEFAULT_MAX_SIZE; wl_array_init(&display->additional_shm_formats); @@ -1550,6 +1554,36 @@ wl_display_destroy_clients(struct wl_display *display) } } +/** Sets the default maximum size for connection buffers of new clients + * + * \param display The display object + * \param max_buffer_size The default maximum size of the connection buffers + * + * This function sets the default size of the internal connection buffers for + * new clients, it doesn't change the buffer size for existing wl_client. + * + * The connection buffer size of each existing wl_client can be adjusted using + * wl_client_set_max_buffer_size(). + * + * The actual size of the connection buffers is a power of two, the requested + * \a max_buffer_size is therefore rounded up to the nearest power of two value. + * + * The minimum buffer size is 4096. + * + * \sa wl_client_set_max_buffer_size + * + * \memberof wl_display + */ +WL_EXPORT void +wl_display_set_default_max_buffer_size(struct wl_display *display, + size_t max_buffer_size) +{ + if (max_buffer_size < WL_BUFFER_DEFAULT_MAX_SIZE) + max_buffer_size = WL_BUFFER_DEFAULT_MAX_SIZE; + + display->max_buffer_size = max_buffer_size; +} + static int socket_data(int fd, uint32_t mask, void *data) { @@ -2245,6 +2279,33 @@ wl_signal_emit_mutable(struct wl_signal *signal, void *data) wl_list_remove(&end.link); } +/** Adjust the maximum size of the client connection buffers + * + * \param client The client object + * \param max_buffer_size The maximum size of the connection buffers + * + * The actual size of the connection buffers is a power of two, the requested + * \a max_buffer_size is therefore rounded up to the nearest power of two value. + * + * Lowering the maximum size may not take effect immediately if the current content + * of the buffer does not fit within the new size limit. + * + * The minimum buffer size is 4096. The default buffers size can be set using + * wl_display_set_default_max_buffer_size() + * + * \sa wl_display_set_default_max_buffer_size() + * + * \memberof wl_client + */ +WL_EXPORT void +wl_client_set_max_buffer_size(struct wl_client *client, size_t max_buffer_size) +{ + if (max_buffer_size < WL_BUFFER_DEFAULT_MAX_SIZE) + max_buffer_size = WL_BUFFER_DEFAULT_MAX_SIZE; + + wl_connection_set_max_buffer_size(client->connection, max_buffer_size); +} + /** \cond INTERNAL */ /** Initialize a wl_priv_signal object diff --git a/tests/connection-test.c b/tests/connection-test.c index 9762e0d..0c76045 100644 --- a/tests/connection-test.c +++ b/tests/connection-test.c @@ -50,7 +50,7 @@ setup(int *s) assert(socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, s) == 0); - connection = wl_connection_create(s[0]); + connection = wl_connection_create(s[0], WL_BUFFER_DEFAULT_MAX_SIZE); assert(connection); return connection; @@ -183,9 +183,11 @@ setup_marshal_data(struct marshal_data *data) { assert(socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, data->s) == 0); - data->read_connection = wl_connection_create(data->s[0]); + data->read_connection = wl_connection_create(data->s[0], + WL_BUFFER_DEFAULT_MAX_SIZE); assert(data->read_connection); - data->write_connection = wl_connection_create(data->s[1]); + data->write_connection = wl_connection_create(data->s[1], + WL_BUFFER_DEFAULT_MAX_SIZE); assert(data->write_connection); } @@ -277,6 +279,25 @@ expected_fail_marshal(int expected_error, const char *format, ...) assert(errno == expected_error); } +static void +marshal_send(struct marshal_data *data, const char *format, ...) +{ + struct wl_closure *closure; + static const uint32_t opcode = 4444; + static struct wl_object sender = { NULL, NULL, 1234 }; + struct wl_message message = { "test", format, NULL }; + va_list ap; + + 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); +} + static void expected_fail_marshal_send(struct marshal_data *data, int expected_error, const char *format, ...) @@ -644,6 +665,25 @@ TEST(connection_marshal_too_big) free(big_string); } +TEST(connection_marshal_big_enough) +{ + struct marshal_data data; + char *big_string = malloc(5000); + + assert(big_string); + + memset(big_string, ' ', 4999); + big_string[4999] = '\0'; + + setup_marshal_data(&data); + wl_connection_set_max_buffer_size(data.write_connection, 5120); + + marshal_send(&data, "s", big_string); + + release_marshal_data(&data); + free(big_string); +} + static void marshal_helper(const char *format, void *handler, ...) { diff --git a/tests/display-test.c b/tests/display-test.c index bcb3267..6fc136d 100644 --- a/tests/display-test.c +++ b/tests/display-test.c @@ -1513,10 +1513,7 @@ send_overflow_client(void *data) /* Do not close the pipe file descriptors afterwards, because the leak * check verifies that the initial/final FD counts are the same */ assert(write(pipes[1], &tmp, sizeof(tmp)) == (ssize_t)sizeof(tmp)); - - /* Expect an error */ - fprintf(stderr, "Send loop failed on try %d, err = %d, %s\n", i, err, strerror(err)); - assert(err == EAGAIN); + assert(err == 0); client_disconnect_nocheck(c); } diff --git a/tests/os-wrappers-test.c b/tests/os-wrappers-test.c index 8d8c3ab..e65a5d6 100644 --- a/tests/os-wrappers-test.c +++ b/tests/os-wrappers-test.c @@ -256,10 +256,12 @@ setup_marshal_data(struct marshal_data *data) assert(socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, data->s) == 0); - data->read_connection = wl_connection_create(data->s[0]); + data->read_connection = wl_connection_create(data->s[0], + WL_BUFFER_DEFAULT_MAX_SIZE); assert(data->read_connection); - data->write_connection = wl_connection_create(data->s[1]); + data->write_connection = wl_connection_create(data->s[1], + WL_BUFFER_DEFAULT_MAX_SIZE); assert(data->write_connection); } -- 2.17.1