mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2025-10-29 05:40:16 -04:00
Merge branch 'cleanups' into 'main'
Miscellaneous cleanups See merge request wayland/wayland!414
This commit is contained in:
commit
7d5c30246a
2 changed files with 144 additions and 29 deletions
170
src/connection.c
170
src/connection.c
|
|
@ -93,19 +93,45 @@ ring_buffer_mask(const struct wl_ring_buffer *b, size_t i) {
|
||||||
return i & m;
|
return i & m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
ring_buffer_size(struct wl_ring_buffer *b)
|
||||||
|
{
|
||||||
|
return b->head - b->tail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Precondition: the data will not overflow the buffer */
|
||||||
static int
|
static int
|
||||||
ring_buffer_put(struct wl_ring_buffer *b, const void *data, size_t count)
|
ring_buffer_put(struct wl_ring_buffer *b, const void *data, size_t count)
|
||||||
{
|
{
|
||||||
size_t head, size;
|
size_t head, size, buffer_size, capacity;
|
||||||
|
|
||||||
|
if (b->head < b->tail) {
|
||||||
|
wl_abort("ring_buffer_put: ring buffer corrupt, %zu < %zu\n",
|
||||||
|
b->head, b->tail);
|
||||||
|
}
|
||||||
|
|
||||||
|
capacity = ring_buffer_capacity(b);
|
||||||
|
buffer_size = ring_buffer_size(b);
|
||||||
|
if (buffer_size > capacity) {
|
||||||
|
wl_abort("ring_buffer_put: ring buffer corrupt: "
|
||||||
|
"%zu - %zu > %zu\n", b->head, b->tail, capacity);
|
||||||
|
}
|
||||||
|
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (capacity - buffer_size < count) {
|
||||||
|
wl_abort("ring_buffer_put: attempt to overfill buffer: "
|
||||||
|
"%zu - %zu < %zu\n", capacity, buffer_size, count);
|
||||||
|
}
|
||||||
|
|
||||||
head = ring_buffer_mask(b, b->head);
|
head = ring_buffer_mask(b, b->head);
|
||||||
if (head + count <= ring_buffer_capacity(b)) {
|
size = capacity - head;
|
||||||
|
if (count <= size) {
|
||||||
|
/* Enough space after head to fulfill request */
|
||||||
memcpy(b->data + head, data, count);
|
memcpy(b->data + head, data, count);
|
||||||
} else {
|
} else {
|
||||||
size = ring_buffer_capacity(b) - head;
|
/* Need to wrap around */
|
||||||
memcpy(b->data + head, data, size);
|
memcpy(b->data + head, data, size);
|
||||||
memcpy(b->data, (const char *) data + size, count - size);
|
memcpy(b->data, (const char *) data + size, count - size);
|
||||||
}
|
}
|
||||||
|
|
@ -115,78 +141,160 @@ ring_buffer_put(struct wl_ring_buffer *b, const void *data, size_t count)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Precondition: the buffer is not full */
|
||||||
static void
|
static void
|
||||||
ring_buffer_put_iov(struct wl_ring_buffer *b, struct iovec *iov, int *count)
|
ring_buffer_put_iov(struct wl_ring_buffer *b, struct iovec *iov, int *count)
|
||||||
{
|
{
|
||||||
size_t head, tail;
|
size_t head, tail, size, capacity;
|
||||||
|
|
||||||
|
if (b->head < b->tail) {
|
||||||
|
wl_abort("ring_buffer_put_iov: ring buffer corrupt, %zu < %zu\n",
|
||||||
|
b->head, b->tail);
|
||||||
|
}
|
||||||
|
|
||||||
|
size = ring_buffer_size(b);
|
||||||
|
capacity = ring_buffer_capacity(b);
|
||||||
|
if (size >= capacity) {
|
||||||
|
wl_abort("ring_buffer_put_iov: ring buffer full or corrupt: "
|
||||||
|
"%zu - %zu >= %zu\n", b->head, b->tail, capacity);
|
||||||
|
}
|
||||||
|
|
||||||
head = ring_buffer_mask(b, b->head);
|
head = ring_buffer_mask(b, b->head);
|
||||||
tail = ring_buffer_mask(b, b->tail);
|
tail = ring_buffer_mask(b, b->tail);
|
||||||
if (head < tail) {
|
if (head < tail) {
|
||||||
|
/* Buffer is like this:
|
||||||
|
* head tail
|
||||||
|
* | |
|
||||||
|
* +---------+-----------------+---------+
|
||||||
|
* | VALID | INVALID | VALID |
|
||||||
|
* +---------+-----------------+---------+
|
||||||
|
*/
|
||||||
iov[0].iov_base = b->data + head;
|
iov[0].iov_base = b->data + head;
|
||||||
iov[0].iov_len = tail - head;
|
iov[0].iov_len = tail - head;
|
||||||
*count = 1;
|
*count = 1;
|
||||||
} else if (tail == 0) {
|
} else if (tail == 0) {
|
||||||
|
/* Buffer is like this:
|
||||||
|
* tail head
|
||||||
|
* | |
|
||||||
|
* +---------------------------+---------+
|
||||||
|
* | VALID | INVALID |
|
||||||
|
* +---------------------------+---------+
|
||||||
|
*/
|
||||||
iov[0].iov_base = b->data + head;
|
iov[0].iov_base = b->data + head;
|
||||||
iov[0].iov_len = ring_buffer_capacity(b) - head;
|
iov[0].iov_len = capacity - head;
|
||||||
*count = 1;
|
*count = 1;
|
||||||
} else {
|
} else {
|
||||||
|
/* Buffer is like this:
|
||||||
|
* tail head
|
||||||
|
* | |
|
||||||
|
* +---------------------------+---------+
|
||||||
|
* | INVALID | VALID | INVALID |
|
||||||
|
* +---------------------------+---------+
|
||||||
|
*/
|
||||||
iov[0].iov_base = b->data + head;
|
iov[0].iov_base = b->data + head;
|
||||||
iov[0].iov_len = ring_buffer_capacity(b) - head;
|
iov[0].iov_len = capacity - head;
|
||||||
iov[1].iov_base = b->data;
|
iov[1].iov_base = b->data;
|
||||||
iov[1].iov_len = tail;
|
iov[1].iov_len = tail;
|
||||||
*count = 2;
|
*count = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Precondition: the buffer is not empty */
|
||||||
static void
|
static void
|
||||||
ring_buffer_get_iov(struct wl_ring_buffer *b, struct iovec *iov, int *count)
|
ring_buffer_get_iov(struct wl_ring_buffer *b, struct iovec *iov, int *count)
|
||||||
{
|
{
|
||||||
size_t head, tail;
|
size_t head, tail, capacity;
|
||||||
|
|
||||||
|
if (b->head <= b->tail) {
|
||||||
|
wl_abort("ring_buffer_get_iov(): empty or corrupt buffer: %zu <= %zu\n",
|
||||||
|
b->head, b->tail);
|
||||||
|
}
|
||||||
|
|
||||||
|
capacity = ring_buffer_capacity(b);
|
||||||
|
if (ring_buffer_size(b) > capacity) {
|
||||||
|
wl_abort("ring_buffer_put_iov: ring buffer corrupt: "
|
||||||
|
"%zu - %zu > %zu\n", b->head, b->tail, capacity);
|
||||||
|
}
|
||||||
|
|
||||||
head = ring_buffer_mask(b, b->head);
|
head = ring_buffer_mask(b, b->head);
|
||||||
tail = ring_buffer_mask(b, b->tail);
|
tail = ring_buffer_mask(b, b->tail);
|
||||||
if (tail < head) {
|
if (tail < head) {
|
||||||
|
/* Buffer is like this:
|
||||||
|
* tail head
|
||||||
|
* | |
|
||||||
|
* +---------+-----------------+---------+
|
||||||
|
* | INVALID | VALID | INVALID |
|
||||||
|
* +---------+-----------------+---------+
|
||||||
|
*/
|
||||||
iov[0].iov_base = b->data + tail;
|
iov[0].iov_base = b->data + tail;
|
||||||
iov[0].iov_len = head - tail;
|
iov[0].iov_len = head - tail;
|
||||||
*count = 1;
|
*count = 1;
|
||||||
} else if (head == 0) {
|
} else if (head == 0) {
|
||||||
|
/* Buffer is like this:
|
||||||
|
* head tail
|
||||||
|
* | |
|
||||||
|
* +---------------------------+---------+
|
||||||
|
* | INVALID | VALID |
|
||||||
|
* +---------------------------+---------+
|
||||||
|
*/
|
||||||
iov[0].iov_base = b->data + tail;
|
iov[0].iov_base = b->data + tail;
|
||||||
iov[0].iov_len = ring_buffer_capacity(b) - tail;
|
iov[0].iov_len = capacity - tail;
|
||||||
*count = 1;
|
*count = 1;
|
||||||
} else {
|
} else {
|
||||||
|
/* Buffer is like this:
|
||||||
|
* head tail
|
||||||
|
* | |
|
||||||
|
* +-------+-------------------+---------+
|
||||||
|
* | VALID | INVALID | VALID |
|
||||||
|
* +---------------------------+---------+
|
||||||
|
*/
|
||||||
iov[0].iov_base = b->data + tail;
|
iov[0].iov_base = b->data + tail;
|
||||||
iov[0].iov_len = ring_buffer_capacity(b) - tail;
|
iov[0].iov_len = capacity - tail;
|
||||||
iov[1].iov_base = b->data;
|
iov[1].iov_base = b->data;
|
||||||
iov[1].iov_len = head;
|
iov[1].iov_len = head;
|
||||||
*count = 2;
|
*count = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Precondition: the data will not underflow the buffer */
|
||||||
static void
|
static void
|
||||||
ring_buffer_copy(struct wl_ring_buffer *b, void *data, size_t count)
|
ring_buffer_copy(struct wl_ring_buffer *b, void *data, size_t count)
|
||||||
{
|
{
|
||||||
size_t tail, size;
|
size_t tail, size, buffer_size, capacity;
|
||||||
|
|
||||||
|
if (b->head < b->tail) {
|
||||||
|
wl_abort("ring_buffer_copy(): ring buffer corrupt, %zu < %zu\n",
|
||||||
|
b->head, b->tail);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer_size = ring_buffer_size(b);
|
||||||
|
capacity = ring_buffer_capacity(b);
|
||||||
|
if (buffer_size > capacity) {
|
||||||
|
wl_abort("ring_buffer_copy(): ring buffer corrupt: "
|
||||||
|
"%zu - %zu > %zu\n", b->head, b->tail, capacity);
|
||||||
|
}
|
||||||
|
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (buffer_size < count) {
|
||||||
|
wl_abort("ring_buffer_copy(): attempt to copy %zu bytes "
|
||||||
|
"but buffer has %zu bytes\n",
|
||||||
|
count, buffer_size);
|
||||||
|
}
|
||||||
|
|
||||||
tail = ring_buffer_mask(b, b->tail);
|
tail = ring_buffer_mask(b, b->tail);
|
||||||
if (tail + count <= ring_buffer_capacity(b)) {
|
size = capacity - tail;
|
||||||
|
if (count <= size) {
|
||||||
|
/* Enough data after the tail to fulfill the request */
|
||||||
memcpy(data, b->data + tail, count);
|
memcpy(data, b->data + tail, count);
|
||||||
} else {
|
} else {
|
||||||
size = ring_buffer_capacity(b) - tail;
|
/* Must wrap buffer around */
|
||||||
memcpy(data, b->data + tail, size);
|
memcpy(data, b->data + tail, size);
|
||||||
memcpy((char *) data + size, b->data, count - size);
|
memcpy((char *) data + size, b->data, count - size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
|
||||||
ring_buffer_size(struct wl_ring_buffer *b)
|
|
||||||
{
|
|
||||||
return b->head - b->tail;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
ring_buffer_tail(const struct wl_ring_buffer *b)
|
ring_buffer_tail(const struct wl_ring_buffer *b)
|
||||||
{
|
{
|
||||||
|
|
@ -415,7 +523,7 @@ decode_cmsg(struct wl_ring_buffer *buffer, struct msghdr *msg)
|
||||||
{
|
{
|
||||||
struct cmsghdr *cmsg;
|
struct cmsghdr *cmsg;
|
||||||
size_t size, i;
|
size_t size, i;
|
||||||
int overflow = 0;
|
bool overflow = false;
|
||||||
|
|
||||||
for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL;
|
for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL;
|
||||||
cmsg = CMSG_NXTHDR(msg, cmsg)) {
|
cmsg = CMSG_NXTHDR(msg, cmsg)) {
|
||||||
|
|
@ -426,7 +534,7 @@ decode_cmsg(struct wl_ring_buffer *buffer, struct msghdr *msg)
|
||||||
size = cmsg->cmsg_len - CMSG_LEN(0);
|
size = cmsg->cmsg_len - CMSG_LEN(0);
|
||||||
|
|
||||||
if (ring_buffer_ensure_space(buffer, size) < 0 || overflow) {
|
if (ring_buffer_ensure_space(buffer, size) < 0 || overflow) {
|
||||||
overflow = 1;
|
overflow = true;
|
||||||
size /= sizeof(int32_t);
|
size /= sizeof(int32_t);
|
||||||
for (i = 0; i < size; i++)
|
for (i = 0; i < size; i++)
|
||||||
close(((int*)CMSG_DATA(cmsg))[i]);
|
close(((int*)CMSG_DATA(cmsg))[i]);
|
||||||
|
|
@ -458,6 +566,9 @@ wl_connection_flush(struct wl_connection *connection)
|
||||||
|
|
||||||
tail = connection->out.tail;
|
tail = connection->out.tail;
|
||||||
while (ring_buffer_size(&connection->out) > 0) {
|
while (ring_buffer_size(&connection->out) > 0) {
|
||||||
|
/* Ring buffer is not empty, so this is safe. */
|
||||||
|
ring_buffer_get_iov(&connection->out, iov, &count);
|
||||||
|
|
||||||
build_cmsg(&connection->fds_out, cmsg, &clen);
|
build_cmsg(&connection->fds_out, cmsg, &clen);
|
||||||
|
|
||||||
if (clen >= CLEN) {
|
if (clen >= CLEN) {
|
||||||
|
|
@ -532,6 +643,7 @@ wl_connection_read(struct wl_connection *connection)
|
||||||
if (ring_buffer_ensure_space(&connection->in, 1) < 0)
|
if (ring_buffer_ensure_space(&connection->in, 1) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
/* Ring buffer is not full, so this is safe. */
|
||||||
ring_buffer_put_iov(&connection->in, iov, &count);
|
ring_buffer_put_iov(&connection->in, iov, &count);
|
||||||
|
|
||||||
msg.msg_name = NULL;
|
msg.msg_name = NULL;
|
||||||
|
|
@ -685,6 +797,7 @@ wl_message_get_since(const struct wl_message *message)
|
||||||
{
|
{
|
||||||
int since;
|
int since;
|
||||||
|
|
||||||
|
/* This is trusted input */
|
||||||
since = atoi(message->signature);
|
since = atoi(message->signature);
|
||||||
|
|
||||||
if (since == 0)
|
if (since == 0)
|
||||||
|
|
@ -952,14 +1065,14 @@ wl_connection_demarshal(struct wl_connection *connection,
|
||||||
case WL_ARG_STRING:
|
case WL_ARG_STRING:
|
||||||
length = *p++;
|
length = *p++;
|
||||||
|
|
||||||
if (length == 0 && !arg.nullable) {
|
|
||||||
wl_log("NULL string received on non-nullable "
|
|
||||||
"type, message %s(%s)\n", message->name,
|
|
||||||
message->signature);
|
|
||||||
errno = EINVAL;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
|
if (!arg.nullable) {
|
||||||
|
wl_log("NULL string received on non-nullable "
|
||||||
|
"type, message %s(%s)\n", message->name,
|
||||||
|
message->signature);
|
||||||
|
errno = EINVAL;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
closure->args[i].s = NULL;
|
closure->args[i].s = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1062,7 +1175,10 @@ wl_connection_demarshal(struct wl_connection *connection,
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This ring buffer will always have a multiple of sizeof(int)
|
||||||
|
* bytes in it. */
|
||||||
ring_buffer_copy(&connection->fds_in, &fd, sizeof fd);
|
ring_buffer_copy(&connection->fds_in, &fd, sizeof fd);
|
||||||
|
/* This can wrap but that is okay. */
|
||||||
connection->fds_in.tail += sizeof fd;
|
connection->fds_in.tail += sizeof fd;
|
||||||
closure->args[i].h = fd;
|
closure->args[i].h = fd;
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -740,8 +740,7 @@ wl_client_post_implementation_error(struct wl_client *client,
|
||||||
WL_EXPORT void
|
WL_EXPORT void
|
||||||
wl_resource_post_no_memory(struct wl_resource *resource)
|
wl_resource_post_no_memory(struct wl_resource *resource)
|
||||||
{
|
{
|
||||||
wl_resource_post_error(resource->client->display_resource,
|
wl_client_post_no_memory(resource->client);
|
||||||
WL_DISPLAY_ERROR_NO_MEMORY, "no memory");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Detect if a wl_resource uses the deprecated public definition.
|
/** Detect if a wl_resource uses the deprecated public definition.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue