summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorAlexandre Ratchov <ratchov@cvs.openbsd.org>2024-07-23 06:34:04 +0000
committerAlexandre Ratchov <ratchov@cvs.openbsd.org>2024-07-23 06:34:04 +0000
commit19fb8b273f7235758c33de112b1bfbd866528a84 (patch)
tree8c224c1d2514953fdd5c24ac8ca596093fa14b26 /usr.bin
parentfe1f61086b39dd6ee1ddd5dda3880153bebae14f (diff)
sndiod: Properly update the poll(2) event masks after i/o.
If there are no descriptors to poll for an event source, we call the i/o handlers immediately (before poll(2) is called). As this may generate output for other descriptors, their the poll(2) event masks need to be updated.
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/sndiod/file.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/usr.bin/sndiod/file.c b/usr.bin/sndiod/file.c
index 3fb8664f529..64a235741b9 100644
--- a/usr.bin/sndiod/file.c
+++ b/usr.bin/sndiod/file.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: file.c,v 1.26 2022/12/26 19:16:03 jmc Exp $ */
+/* $OpenBSD: file.c,v 1.27 2024/07/23 06:34:03 ratchov Exp $ */
/*
* Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org>
*
@@ -63,7 +63,7 @@
void timo_update(unsigned int);
void timo_init(void);
void timo_done(void);
-void file_process(struct file *, struct pollfd *);
+int file_process(struct file *, struct pollfd *);
struct timespec file_ts;
struct file *file_list;
@@ -270,10 +270,10 @@ file_del(struct file *f)
#endif
}
-void
+int
file_process(struct file *f, struct pollfd *pfd)
{
- int revents;
+ int rc, revents;
#ifdef DEBUG
struct timespec ts0, ts1;
long us;
@@ -283,14 +283,21 @@ file_process(struct file *f, struct pollfd *pfd)
if (log_level >= 3)
clock_gettime(CLOCK_UPTIME, &ts0);
#endif
+ rc = 0;
revents = (f->state != FILE_ZOMB) ?
f->ops->revents(f->arg, pfd) : 0;
- if ((revents & POLLHUP) && (f->state != FILE_ZOMB))
+ if ((revents & POLLHUP) && (f->state != FILE_ZOMB)) {
f->ops->hup(f->arg);
- if ((revents & POLLIN) && (f->state != FILE_ZOMB))
+ rc = 1;
+ }
+ if ((revents & POLLIN) && (f->state != FILE_ZOMB)) {
f->ops->in(f->arg);
- if ((revents & POLLOUT) && (f->state != FILE_ZOMB))
+ rc = 1;
+ }
+ if ((revents & POLLOUT) && (f->state != FILE_ZOMB)) {
f->ops->out(f->arg);
+ rc = 1;
+ }
#ifdef DEBUG
if (log_level >= 3) {
clock_gettime(CLOCK_UPTIME, &ts1);
@@ -304,6 +311,7 @@ file_process(struct file *f, struct pollfd *pfd)
}
}
#endif
+ return rc;
}
int
@@ -370,11 +378,19 @@ file_poll(void)
/*
* process files that do not rely on poll
*/
+ res = 0;
for (f = file_list; f != NULL; f = f->next) {
if (f->nfds > 0)
continue;
- file_process(f, NULL);
+ res |= file_process(f, NULL);
}
+ /*
+ * The processing may have changed the poll(2) conditions of
+ * other files, so restart the loop to force their poll(2) event
+ * masks to be reevaluated.
+ */
+ if (res)
+ return 1;
/*
* Sleep. Calculate the number of milliseconds poll(2) must