 9ba65d2ea8
			
		
	
	
		9ba65d2ea8
		
	
	
	
	
		
			
			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.
		
			
				
	
	
		
			120 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			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;
 | |
| }
 |