diff options
| author | Kenny Levinsen <kl@kl.wtf> | 2021-07-09 00:09:14 +0200 | 
|---|---|---|
| committer | Kenny Levinsen <kl@kl.wtf> | 2021-07-09 00:09:14 +0200 | 
| commit | 5923e0edc9bb157cf6398b63d51cc3c0aaf06001 (patch) | |
| tree | ed84422f263bc6739b6138502c509f947351d1d3 | |
| parent | 7a6d12ff7a4e3e19d6c7c9e0f2d270491168e785 (diff) | |
| download | seatd-5923e0edc9bb157cf6398b63d51cc3c0aaf06001.tar.xz | |
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.
| -rw-r--r-- | libseat/backend/seatd.c | 37 | 
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) {  | 
