From 5923e0edc9bb157cf6398b63d51cc3c0aaf06001 Mon Sep 17 00:00:00 2001 From: Kenny Levinsen Date: Fri, 9 Jul 2021 00:09:14 +0200 Subject: libseat/seatd: Add dispatch_pending_and_execute This handler returns the number of dispatched or executed events, or -1 if dispatch_pending failed. This helper is used to clean up dispatch_background, which now ensures that all events are executed before we read or poll the connection, and have improved error handling in the corner case where the second dispatch_pending failed. --- libseat/backend/seatd.c | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) (limited to 'libseat') diff --git a/libseat/backend/seatd.c b/libseat/backend/seatd.c index 9bc5e6e..3600b50 100644 --- a/libseat/backend/seatd.c +++ b/libseat/backend/seatd.c @@ -262,6 +262,15 @@ static int dispatch_pending(struct backend_seatd *backend, int *opcode) { return packets; } +static int dispatch_pending_and_execute(struct backend_seatd *backend) { + int dispatched = dispatch_pending(backend, NULL); + if (dispatched == -1) { + return -1; + } + dispatched += execute_events(backend); + return dispatched; +} + static int poll_connection(struct backend_seatd *backend, int timeout) { struct pollfd fd = { .fd = backend->connection.fd, @@ -324,28 +333,34 @@ static int dispatch_background(struct libseat *base, int timeout) { return -1; } - int dispatched = dispatch_pending(backend, NULL); - if (dispatched > 0) { - // We don't want to block if we dispatched something, as the - // caller might be waiting for the result. However, we'd also - // like to read anything pending. - timeout = 0; + int predispatch = dispatch_pending_and_execute(backend); + if (predispatch == -1) { + return -1; } + + // We don't want to block if we dispatched something, as the + // caller might be waiting for the result. However, we'd also + // like to read anything pending. int read = 0; - if (timeout == 0) { + if (predispatch == 0 || timeout == 0) { read = connection_read(&backend->connection); } else { read = poll_connection(backend, timeout); } - if (read > 0) { - dispatched += dispatch_pending(backend, NULL); + + if (read == 0) { + return predispatch; } else if (read == -1 && errno != EAGAIN) { log_errorf("Could not read from connection: %s", strerror(errno)); return -1; } - dispatched += execute_events(backend); - return dispatched; + int postdispatch = dispatch_pending_and_execute(backend); + if (postdispatch == -1) { + return -1; + } + + return predispatch + postdispatch; } static struct libseat *_open_seat(struct libseat_seat_listener *listener, void *data, int fd) { -- cgit v1.2.3