aboutsummaryrefslogtreecommitdiff
path: root/iopause.c
diff options
context:
space:
mode:
authorHenryk Plötz <henryk@ploetzli.ch>2014-10-03 19:58:52 +0200
committerHenryk Plötz <henryk@ploetzli.ch>2014-10-03 19:58:52 +0200
commit0e5b2871ca6456b01d4bf037a6e68badf1ff1a41 (patch)
tree97b95b74c9618d85da9aa9451a55a819cd7b1c2e /iopause.c
downloadtinydnssec-0e5b2871ca6456b01d4bf037a6e68badf1ff1a41.tar.gz
tinydnssec-0e5b2871ca6456b01d4bf037a6e68badf1ff1a41.tar.bz2
Initial commit of djbdns-1.05.tar.gz
Source was http://cr.yp.to/djbdns/djbdns-1.05.tar.gz, SHA1 2efdb3a039d0c548f40936aa9cb30829e0ce8c3d
Diffstat (limited to 'iopause.c')
-rw-r--r--iopause.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/iopause.c b/iopause.c
new file mode 100644
index 0000000..b8034de
--- /dev/null
+++ b/iopause.c
@@ -0,0 +1,76 @@
+#include "taia.h"
+#include "select.h"
+#include "iopause.h"
+
+void iopause(iopause_fd *x,unsigned int len,struct taia *deadline,struct taia *stamp)
+{
+ struct taia t;
+ int millisecs;
+ double d;
+ int i;
+
+ if (taia_less(deadline,stamp))
+ millisecs = 0;
+ else {
+ t = *stamp;
+ taia_sub(&t,deadline,&t);
+ d = taia_approx(&t);
+ if (d > 1000.0) d = 1000.0;
+ millisecs = d * 1000.0 + 20.0;
+ }
+
+ for (i = 0;i < len;++i)
+ x[i].revents = 0;
+
+#ifdef IOPAUSE_POLL
+
+ poll(x,len,millisecs);
+ /* XXX: some kernels apparently need x[0] even if len is 0 */
+ /* XXX: how to handle EAGAIN? are kernels really this dumb? */
+ /* XXX: how to handle EINVAL? when exactly can this happen? */
+
+#else
+{
+
+ struct timeval tv;
+ fd_set rfds;
+ fd_set wfds;
+ int nfds;
+ int fd;
+
+ FD_ZERO(&rfds);
+ FD_ZERO(&wfds);
+
+ nfds = 1;
+ for (i = 0;i < len;++i) {
+ fd = x[i].fd;
+ if (fd < 0) continue;
+ if (fd >= 8 * sizeof(fd_set)) continue; /*XXX*/
+
+ if (fd >= nfds) nfds = fd + 1;
+ if (x[i].events & IOPAUSE_READ) FD_SET(fd,&rfds);
+ if (x[i].events & IOPAUSE_WRITE) FD_SET(fd,&wfds);
+ }
+
+ tv.tv_sec = millisecs / 1000;
+ tv.tv_usec = 1000 * (millisecs % 1000);
+
+ if (select(nfds,&rfds,&wfds,(fd_set *) 0,&tv) <= 0)
+ return;
+ /* XXX: for EBADF, could seek out and destroy the bad descriptor */
+
+ for (i = 0;i < len;++i) {
+ fd = x[i].fd;
+ if (fd < 0) continue;
+ if (fd >= 8 * sizeof(fd_set)) continue; /*XXX*/
+
+ if (x[i].events & IOPAUSE_READ)
+ if (FD_ISSET(fd,&rfds)) x[i].revents |= IOPAUSE_READ;
+ if (x[i].events & IOPAUSE_WRITE)
+ if (FD_ISSET(fd,&wfds)) x[i].revents |= IOPAUSE_WRITE;
+ }
+
+}
+#endif
+
+}