minix/lib/libc/asyn/asyn_wait.c
David van Moolenbroek 9ba65d2ea8 This patch switches the MINIX3 ethernet driver stack from a port-based
model to an instance-based model. Each ethernet driver instance is now
responsible for exactly one network interface card. The port field in
/etc/inet.conf now acts as an instance field instead.

This patch also updates the data link protocol. This update:
- eliminates the concept of ports entirely;
- eliminates DL_GETNAME entirely;
- standardizes on using m_source for IPC and DL_ENDPT for safecopies;
- removes error codes from TASK/STAT replies, as they were unused;
- removes a number of other old or unused fields;
- names and renames a few other fields.

All ethernet drivers have been changed to:
- conform to the new protocol, and exactly that;
- take on an instance number based on a given "instance" argument;
- skip that number of PCI devices in probe iterations;
- use config tables and environment variables based on that number;
- no longer be limited to a predefined maximum of cards in any way;
- get rid of any leftover non-safecopy support and other ancient junk;
- have a correct banner protocol figure, or none at all.

Other changes:
* Inet.conf is now taken to be line-based, and supports #-comments.
  No existing installations are expected to be affected by this.
* A new, select-based asynchio library replaces the old one.
  Kindly contributed by Kees J. Bot.
* Inet now supports use of select() on IP devices.
  Combined, the last two changes together speed up dhcpd
  considerably in the presence of multiple interfaces.
* A small bug has been fixed in nonamed.
2010-05-17 22:22:53 +00:00

120 lines
2.6 KiB
C

/* asyn_wait() - wait for asynch operations Author: Kees J. Bot
* 7 Jul 1997
*/
#define DEBUG 0
#include "asyn.h"
#include <time.h>
#if DEBUG
#include <stdio.h>
#endif
#define TBOUND_MIN 1
#define TBOUND_MAX 16
int asyn_wait(asynchio_t *asyn, int flags, struct timeval *to)
/* Wait for one or more nonblocking operations to return a result. */
{
int r;
static struct timeval zero_time;
struct timeval t;
static time_t tbound= TBOUND_MIN;
/* Are there more things to do before we can block? */
if (asyn->asyn_more > 0) { asyn->asyn_more= 0; return 0; }
if (flags & ASYN_NONBLOCK) {
/* Don't block by using a zero second timeout. */
to= &zero_time;
} else
if (to != nil) {
/* asyn_wait() uses an absolute time. */
if (to->tv_usec >= 1000000L) {
to->tv_sec+= to->tv_usec / 1000000L;
to->tv_usec%= 1000000L;
}
(void) gettimeofday(&t, nil);
if (t.tv_sec > to->tv_sec || (t.tv_sec == to->tv_sec
&& t.tv_usec >= to->tv_usec)) {
to= &zero_time;
} else {
t.tv_sec= to->tv_sec - t.tv_sec;
t.tv_usec= to->tv_usec - t.tv_usec;
if (t.tv_usec < 0) {
t.tv_sec--;
t.tv_usec+= 1000000L;
}
to= &t;
}
/* Don't sleep too long, we don't trust select(). */
if (to->tv_sec > tbound) goto bound;
} else {
bound:
/* No timeout? Don't hang in (buggy?) select() forever. */
to= &t;
t.tv_sec= tbound;
t.tv_usec= 0;
}
#if DEBUG
{
int op;
fprintf(stderr, "select: ");
for (op= 0; op < SEL_NR; op++) {
fd_set *fdsetp= &asyn->asyn_fdset[op];
int fd;
for (fd= 0; fd < FD_SETSIZE; fd++) {
if (FD_ISSET(fd, fdsetp)) {
asyn->asyn_afd[fd].afd_state[op]=
PENDING;
fprintf(stderr, "%d%c", fd, "rwx"[op]);
}
}
}
fflush(stderr);
}
#endif
r= select(FD_SETSIZE, &asyn->asyn_fdset[SEL_READ],
&asyn->asyn_fdset[SEL_WRITE],
&asyn->asyn_fdset[SEL_EXCEPT], to);
#if DEBUG
fprintf(stderr, " (%d) ", r);
#endif
if (r > 0) {
/* An event occurred on one or more file descriptors. */
int op;
for (op= 0; op < SEL_NR; op++) {
fd_set *fdsetp= &asyn->asyn_fdset[op];
int fd;
for (fd= 0; fd < FD_SETSIZE; fd++) {
if (FD_ISSET(fd, fdsetp)) {
asyn->asyn_afd[fd].afd_state[op]=
PENDING;
#if DEBUG
fprintf(stderr, "%d%c", fd, "rwx"[op]);
#endif
}
}
}
tbound= TBOUND_MIN;
} else
if (r == 0) {
/* If nothing happened then let the time boundary slip a bit. */
if (tbound < TBOUND_MAX) tbound <<= 1;
}
#if DEBUG
fputc('\n', stderr);
#endif
FD_ZERO(&asyn->asyn_fdset[SEL_READ]);
FD_ZERO(&asyn->asyn_fdset[SEL_WRITE]);
FD_ZERO(&asyn->asyn_fdset[SEL_EXCEPT]);
return r == 0 ? (errno= EINTR, -1) : r;
}