aboutsummaryrefslogtreecommitdiff
path: root/libseat/backend
diff options
context:
space:
mode:
authorKenny Levinsen <kl@kl.wtf>2021-07-09 00:09:14 +0200
committerKenny Levinsen <kl@kl.wtf>2021-07-09 00:09:14 +0200
commit5923e0edc9bb157cf6398b63d51cc3c0aaf06001 (patch)
treeed84422f263bc6739b6138502c509f947351d1d3 /libseat/backend
parent7a6d12ff7a4e3e19d6c7c9e0f2d270491168e785 (diff)
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.
Diffstat (limited to 'libseat/backend')
-rw-r--r--libseat/backend/seatd.c37
1 files changed, 26 insertions, 11 deletions
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) {