fehQlibs 26
Qlibs
Loading...
Searching...
No Matches
iopause.c
Go to the documentation of this file.
1#include <poll.h>
2#include "taia.h"
3#include "select.h"
4#include "iopause.h"
5
14int iopause(iopause_fd *x,unsigned int len,struct taia *deadline,struct taia *stamp)
15{
16 struct taia t;
17 int millisecs;
18 double d;
19 int i, r;
20
21 if (taia_less(deadline,stamp))
22 millisecs = 0;
23 else {
24 t = *stamp;
25 taia_sub(&t,deadline,&t);
26 d = taia_approx(&t);
27 if (d > 1000.0) d = 1000.0;
28 millisecs = d * 1000.0 + 20.0;
29 if (millisecs < 0) millisecs = 20.0;
30 }
31
32 for (i = 0; i < len; ++i)
33 x[i].revents = 0;
34
35#ifdef IOPAUSE_POLL
36 r = poll(x,len,millisecs);
37
38 /* XXX: some kernels apparently need x[0] even if len is 0 */
39 /* XXX: how to handle EAGAIN? are kernels really this dumb? */
40 /* XXX: how to handle EINVAL? when exactly can this happen? */
41
42#else
43 struct timeval tv;
44 fd_set rfds;
45 fd_set wfds;
46 int nfds;
47 int fd;
48
49 FD_ZERO(&rfds);
50 FD_ZERO(&wfds);
51
52 nfds = 1;
53 for (i = 0; i < len; ++i) {
54 fd = x[i].fd;
55 if (fd < 0) continue;
56 if (fd >= 8 * sizeof(fd_set)) continue; /*XXX*/
57
58 if (fd >= nfds) nfds = fd + 1;
59 if (x[i].events & IOPAUSE_READ) FD_SET(fd,&rfds);
60 if (x[i].events & IOPAUSE_WRITE) FD_SET(fd,&wfds);
61 }
62
63 tv.tv_sec = millisecs / 1000;
64 tv.tv_usec = 1000 * (millisecs % 1000);
65
66 r = select(nfds,&rfds,&wfds,(fd_set *) 0,&tv);
67 if (r <= 0) return r;
68
69 /* XXX: for EBADF, could seek out and destroy the bad descriptor */
70
71 for (i = 0; i < len; ++i) {
72 fd = x[i].fd;
73 if (fd < 0) continue;
74 if (fd >= 8 * sizeof(fd_set)) continue; /*XXX*/
75
76 if (x[i].events & IOPAUSE_READ)
77 if (FD_ISSET(fd,&rfds)) x[i].revents |= IOPAUSE_READ;
78 if (x[i].events & IOPAUSE_WRITE)
79 if (FD_ISSET(fd,&wfds)) x[i].revents |= IOPAUSE_WRITE;
80 }
81
82#endif
83 return r;
84}
int iopause(iopause_fd *x, unsigned int len, struct taia *deadline, struct taia *stamp)
Definition: iopause.c:14
#define IOPAUSE_READ
Definition: iopause.h:19
#define IOPAUSE_WRITE
Definition: iopause.h:20
int select(int, fd_set *, fd_set *, fd_set *, struct timeval *)
void taia_sub(struct taia *, struct taia *, struct taia *)
Definition: taia.c:81
int taia_less(struct taia *, struct taia *)
Definition: taia.c:39
double taia_approx(struct taia *)
Definition: taia.c:29
int fd
Definition: iopause.h:15
short revents
Definition: iopause.h:17
Definition: taia.h:13