Remove building with NOCRYPTO option
[minix3.git] / minix / lib / libasyn / asyn_wait.c
blobc167b0c9e133ee0f074ac6437abd7917ebb41b22
1 /* asyn_wait() - wait for asynch operations Author: Kees J. Bot
2 * 7 Jul 1997
3 */
5 #include "asyn.h"
6 #include <time.h>
7 #ifdef DEBUG
8 #include <stdio.h>
9 #endif
11 #define TBOUND_MIN 1
12 #define TBOUND_MAX 16
14 int asyn_wait(asynchio_t *asyn, int flags, struct timeval *to)
15 /* Wait for one or more nonblocking operations to return a result. */
17 int r;
18 static struct timeval zero_time;
19 struct timeval t;
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. */
27 to= &zero_time;
28 } else
29 if (to != nil) {
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)) {
38 to= &zero_time;
39 } else {
40 t.tv_sec= to->tv_sec - t.tv_sec;
41 t.tv_usec= to->tv_usec - t.tv_usec;
42 if (t.tv_usec < 0) {
43 t.tv_sec--;
44 t.tv_usec+= 1000000L;
46 to= &t;
49 /* Don't sleep too long, we don't trust select(). */
50 if (to->tv_sec > tbound) goto bound;
51 } else {
52 bound:
53 /* No timeout? Don't hang in (buggy?) select() forever. */
54 to= &t;
55 t.tv_sec= tbound;
56 t.tv_usec= 0;
59 #ifdef DEBUG
61 int op;
63 fprintf(stderr, "select: ");
64 for (op= 0; op < SEL_NR; op++) {
65 fd_set *fdsetp= &asyn->asyn_fdset[op];
66 int fd;
68 for (fd= 0; fd < FD_SETSIZE; fd++) {
69 if (FD_ISSET(fd, fdsetp)) {
70 asyn->asyn_afd[fd].afd_state[op]=
71 PENDING;
72 fprintf(stderr, "%d%c", fd, "rwx"[op]);
76 fflush(stderr);
78 #endif
79 r= select(FD_SETSIZE, &asyn->asyn_fdset[SEL_READ],
80 &asyn->asyn_fdset[SEL_WRITE],
81 &asyn->asyn_fdset[SEL_EXCEPT], to);
82 #ifdef DEBUG
83 fprintf(stderr, " (%d) ", r);
84 #endif
85 if (r > 0) {
86 /* An event occurred on one or more file descriptors. */
87 int op;
89 for (op= 0; op < SEL_NR; op++) {
90 fd_set *fdsetp= &asyn->asyn_fdset[op];
91 int fd;
93 for (fd= 0; fd < FD_SETSIZE; fd++) {
94 if (FD_ISSET(fd, fdsetp)) {
95 asyn->asyn_afd[fd].afd_state[op]=
96 PENDING;
97 #ifdef DEBUG
98 fprintf(stderr, "%d%c", fd, "rwx"[op]);
99 #endif
103 tbound= TBOUND_MIN;
104 } else
105 if (r == 0) {
106 /* If nothing happened then let the time boundary slip a bit. */
107 if (tbound < TBOUND_MAX) tbound <<= 1;
109 #ifdef DEBUG
110 fputc('\n', stderr);
111 #endif
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;