1 /* asyn_wait() - wait for asynch operations Author: Kees J. Bot
14 int asyn_wait(asynchio_t
*asyn
, int flags
, struct timeval
*to
)
15 /* Wait for one or more nonblocking operations to return a result. */
18 static struct timeval zero_time
;
20 static time_t tbound
= TBOUND_MIN
;
22 /* Are there more things to do before we can block? */
23 if (asyn
->asyn_more
> 0) { asyn
->asyn_more
= 0; return 0; }
25 if (flags
& ASYN_NONBLOCK
) {
26 /* Don't block by using a zero second timeout. */
30 /* asyn_wait() uses an absolute time. */
31 if (to
->tv_usec
>= 1000000L) {
32 to
->tv_sec
+= to
->tv_usec
/ 1000000L;
33 to
->tv_usec
%= 1000000L;
35 (void) gettimeofday(&t
, nil
);
36 if (t
.tv_sec
> to
->tv_sec
|| (t
.tv_sec
== to
->tv_sec
37 && t
.tv_usec
>= to
->tv_usec
)) {
40 t
.tv_sec
= to
->tv_sec
- t
.tv_sec
;
41 t
.tv_usec
= to
->tv_usec
- t
.tv_usec
;
49 /* Don't sleep too long, we don't trust select(). */
50 if (to
->tv_sec
> tbound
) goto bound
;
53 /* No timeout? Don't hang in (buggy?) select() forever. */
63 fprintf(stderr
, "select: ");
64 for (op
= 0; op
< SEL_NR
; op
++) {
65 fd_set
*fdsetp
= &asyn
->asyn_fdset
[op
];
68 for (fd
= 0; fd
< FD_SETSIZE
; fd
++) {
69 if (FD_ISSET(fd
, fdsetp
)) {
70 asyn
->asyn_afd
[fd
].afd_state
[op
]=
72 fprintf(stderr
, "%d%c", fd
, "rwx"[op
]);
79 r
= select(FD_SETSIZE
, &asyn
->asyn_fdset
[SEL_READ
],
80 &asyn
->asyn_fdset
[SEL_WRITE
],
81 &asyn
->asyn_fdset
[SEL_EXCEPT
], to
);
83 fprintf(stderr
, " (%d) ", r
);
86 /* An event occurred on one or more file descriptors. */
89 for (op
= 0; op
< SEL_NR
; op
++) {
90 fd_set
*fdsetp
= &asyn
->asyn_fdset
[op
];
93 for (fd
= 0; fd
< FD_SETSIZE
; fd
++) {
94 if (FD_ISSET(fd
, fdsetp
)) {
95 asyn
->asyn_afd
[fd
].afd_state
[op
]=
98 fprintf(stderr
, "%d%c", fd
, "rwx"[op
]);
106 /* If nothing happened then let the time boundary slip a bit. */
107 if (tbound
< TBOUND_MAX
) tbound
<<= 1;
113 FD_ZERO(&asyn
->asyn_fdset
[SEL_READ
]);
114 FD_ZERO(&asyn
->asyn_fdset
[SEL_WRITE
]);
115 FD_ZERO(&asyn
->asyn_fdset
[SEL_EXCEPT
]);
117 return r
== 0 ? (errno
= EINTR
, -1) : r
;