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