1 /* asyn_wait() - wait for asynch operations Author: Kees J. Bot
15 int asyn_wait(asynchio_t
*asyn
, int flags
, struct timeval
*to
)
16 /* Wait for one or more nonblocking operations to return a result. */
19 static struct timeval zero_time
;
21 static time_t tbound
= TBOUND_MIN
;
23 /* Are there more things to do before we can block? */
24 if (asyn
->asyn_more
> 0) { asyn
->asyn_more
= 0; return 0; }
26 if (flags
& ASYN_NONBLOCK
) {
27 /* Don't block by using a zero second timeout. */
31 /* asyn_wait() uses an absolute time. */
32 if (to
->tv_usec
>= 1000000L) {
33 to
->tv_sec
+= to
->tv_usec
/ 1000000L;
34 to
->tv_usec
%= 1000000L;
36 (void) gettimeofday(&t
, nil
);
37 if (t
.tv_sec
> to
->tv_sec
|| (t
.tv_sec
== to
->tv_sec
38 && t
.tv_usec
>= to
->tv_usec
)) {
41 t
.tv_sec
= to
->tv_sec
- t
.tv_sec
;
42 t
.tv_usec
= to
->tv_usec
- t
.tv_usec
;
50 /* Don't sleep too long, we don't trust select(). */
51 if (to
->tv_sec
> tbound
) goto bound
;
54 /* No timeout? Don't hang in (buggy?) select() forever. */
64 fprintf(stderr
, "select: ");
65 for (op
= 0; op
< SEL_NR
; op
++) {
66 fd_set
*fdsetp
= &asyn
->asyn_fdset
[op
];
69 for (fd
= 0; fd
< FD_SETSIZE
; fd
++) {
70 if (FD_ISSET(fd
, fdsetp
)) {
71 asyn
->asyn_afd
[fd
].afd_state
[op
]=
73 fprintf(stderr
, "%d%c", fd
, "rwx"[op
]);
80 r
= select(FD_SETSIZE
, &asyn
->asyn_fdset
[SEL_READ
],
81 &asyn
->asyn_fdset
[SEL_WRITE
],
82 &asyn
->asyn_fdset
[SEL_EXCEPT
], to
);
84 fprintf(stderr
, " (%d) ", r
);
87 /* An event occurred on one or more file descriptors. */
90 for (op
= 0; op
< SEL_NR
; op
++) {
91 fd_set
*fdsetp
= &asyn
->asyn_fdset
[op
];
94 for (fd
= 0; fd
< FD_SETSIZE
; fd
++) {
95 if (FD_ISSET(fd
, fdsetp
)) {
96 asyn
->asyn_afd
[fd
].afd_state
[op
]=
99 fprintf(stderr
, "%d%c", fd
, "rwx"[op
]);
107 /* If nothing happened then let the time boundary slip a bit. */
108 if (tbound
< TBOUND_MAX
) tbound
<<= 1;
114 FD_ZERO(&asyn
->asyn_fdset
[SEL_READ
]);
115 FD_ZERO(&asyn
->asyn_fdset
[SEL_WRITE
]);
116 FD_ZERO(&asyn
->asyn_fdset
[SEL_EXCEPT
]);
118 return r
== 0 ? (errno
= EINTR
, -1) : r
;