Commit Diff


commit - e426c131c7260631b2536845159909da2dc92edc
commit + f6e729443e6f1ef72d5687828bfe2bb327d552ac
blob - dd9b05f89e074e34052d66f81d2e95bac063ed6c
blob + 39b994b22fb67b19d41f52339e9d3f8f300ead94
--- src/ngircd/io.c
+++ src/ngircd/io.c
@@ -12,7 +12,7 @@
 
 #include "portab.h"
 
-static char UNUSED id[] = "$Id: io.c,v 1.16 2006/07/23 23:11:44 alex Exp $";
+static char UNUSED id[] = "$Id: io.c,v 1.17 2006/09/16 14:49:26 fw Exp $";
 
 #include <assert.h>
 #include <stdlib.h>
@@ -44,8 +44,8 @@ typedef struct {
 #define IO_USE_KQUEUE   1
 # else
 #define IO_USE_SELECT   1
-#endif
-#endif
+# endif /* HAVE_KQUEUE */
+#endif /* HAVE_EPOLL_CREATE */
 
 static bool library_initialized;
 
@@ -98,40 +98,10 @@ io_event_get(int fd)
 }
 
 
-bool
-io_library_init(unsigned int eventsize)
-{
-#if defined(IO_USE_EPOLL) || defined(IO_USE_KQUEUE)
-	bool ret;
-#endif
-#ifdef IO_USE_EPOLL
-	int ecreate_hint = (int)eventsize;
-	if (ecreate_hint <= 0)
-		ecreate_hint = 128;
-#endif
-	if (library_initialized)
-		return true;
-
 #ifdef IO_USE_SELECT
-#ifdef FD_SETSIZE
-	if (eventsize >= FD_SETSIZE)
-		eventsize = FD_SETSIZE - 1;
-#endif
-#endif
-	if ((eventsize > 0) && !array_alloc(&io_events, sizeof(io_event), (size_t)eventsize))
-		eventsize = 0;
-
-#ifdef IO_USE_EPOLL
-	io_masterfd = epoll_create(ecreate_hint);
-	Log(LOG_INFO,
-	    "IO subsystem: epoll (hint size %d, initial maxfd %u, masterfd %d).",
-	    ecreate_hint, eventsize, io_masterfd);
-	ret = io_masterfd >= 0;
-	if (ret) library_initialized = true;
-
-	return ret;
-#endif
-#ifdef IO_USE_SELECT
+static bool
+io_library_init_select(unsigned int eventsize)
+{
 	Log(LOG_INFO, "IO subsystem: select (initial maxfd %u).",
 	    eventsize);
 	FD_ZERO(&readers);
@@ -144,14 +114,38 @@ io_library_init(unsigned int eventsize)
 
 		Conf_MaxConnections = FD_SETSIZE - 1;
 	}
-#else
-	Log(LOG_WARNING,
-	    "FD_SETSIZE undefined, don't know how many descriptors select() can handle on your platform ...");
 #endif /* FD_SETSIZE */
 	library_initialized = true;
 	return true;
+}
 #endif /* SELECT */
+
+
+#ifdef IO_USE_EPOLL
+static bool
+io_library_init_epoll(unsigned int eventsize)
+{
+	bool ret;
+	int ecreate_hint = (int)eventsize;
+	if (ecreate_hint <= 0)
+		ecreate_hint = 128;
+	io_masterfd = epoll_create(ecreate_hint);
+	Log(LOG_INFO,
+	    "IO subsystem: epoll (hint size %d, initial maxfd %u, masterfd %d).",
+	    ecreate_hint, eventsize, io_masterfd);
+	ret = io_masterfd >= 0;
+	if (ret) library_initialized = true;
+
+	return ret;
+}
+#endif
+
+
 #ifdef IO_USE_KQUEUE
+static bool
+io_library_init_kqueue(unsigned int eventsize)
+{
+	bool ret;
 	io_masterfd = kqueue();
 
 	Log(LOG_INFO,
@@ -159,9 +153,36 @@ io_library_init(unsigned int eventsize)
 	    eventsize, io_masterfd);
 	ret = io_masterfd >= 0;
 	if (ret) library_initialized = true;
-
 	return ret;
+}
 #endif
+
+
+bool
+io_library_init(unsigned int eventsize)
+{
+	if (library_initialized)
+		return true;
+#ifdef IO_USE_SELECT
+#ifndef FD_SETSIZE
+	Log(LOG_WARNING,
+	    "FD_SETSIZE undefined, don't know how many descriptors select() can handle on your platform ...");
+#else
+	if (eventsize >= FD_SETSIZE)
+		eventsize = FD_SETSIZE - 1;
+#endif /* FD_SETSIZE */
+#endif /* IO_USE_SELECT */
+	if ((eventsize > 0) && !array_alloc(&io_events, sizeof(io_event), (size_t)eventsize))
+		eventsize = 0;
+#ifdef IO_USE_EPOLL
+	return io_library_init_epoll(eventsize);
+#endif
+#ifdef IO_USE_KQUEUE
+	return io_library_init_kqueue(eventsize);
+#endif
+#ifdef IO_USE_SELECT
+	return io_library_init_select(eventsize);
+#endif
 }
 
 
@@ -171,11 +192,14 @@ io_library_shutdown(void)
 #ifdef IO_USE_SELECT
 	FD_ZERO(&readers);
 	FD_ZERO(&writers);
-#else
-	close(io_masterfd);	/* kqueue, epoll */
+#endif
+#ifdef IO_USE_EPOLL
+	close(io_masterfd);
 	io_masterfd = -1;
 #endif
 #ifdef IO_USE_KQUEUE
+	close(io_masterfd);
+	io_masterfd = -1;
 	array_free(&io_evcache);
 #endif
 	library_initialized = false;
@@ -201,18 +225,14 @@ io_event_create(int fd, short what, void (*cbfunc) (in
 	io_event *i;
 
 	assert(fd >= 0);
-
-#ifdef IO_USE_SELECT
-#ifdef FD_SETSIZE
+#if defined(IO_USE_SELECT) || defined(FD_SETSIZE)
 	if (fd >= FD_SETSIZE) {
 		Log(LOG_ERR,
 		    "fd %d exceeds FD_SETSIZE (%u) (select can't handle more file descriptors)",
 		    fd, FD_SETSIZE);
 		return false;
 	}
-#endif				/* FD_SETSIZE */
-#endif				/* IO_USE_SELECT */
-
+#endif
 	i = (io_event *) array_alloc(&io_events, sizeof(io_event), (size_t) fd);
 	if (!i) {
 		Log(LOG_WARNING,
@@ -260,7 +280,7 @@ io_event_kqueue_commit_cache(void)
 	struct kevent *events;
 	bool ret;
 	int len = (int) array_length(&io_evcache, sizeof (struct kevent));
- 
+
 	if (!len) /* nothing to do */
 		return true;
 
@@ -293,7 +313,7 @@ io_event_change_kqueue(int fd, short what, const int a
 		ret = array_catb(&io_evcache, (char*) &kev, sizeof (kev));
 		if (!ret)
 			ret = kevent(io_masterfd, &kev,1, NULL, 0, NULL) == 0;
-	}	
+	}
 
 	if (ret && (what & IO_WANTWRITE)) {
 		EV_SET(&kev, fd, EVFILT_WRITE, action, 0, 0, 0);
@@ -327,7 +347,6 @@ io_event_add(int fd, short what)
 #ifdef IO_USE_KQUEUE
 	return io_event_change_kqueue(fd, what, EV_ADD | EV_ENABLE);
 #endif
-
 #ifdef IO_USE_SELECT
 	if (fd > select_maxfd)
 		select_maxfd = fd;
@@ -358,22 +377,35 @@ io_setnonblock(int fd)
 }
 
 
-bool
-io_close(int fd)
+#ifdef IO_USE_SELECT
+static void
+io_close_select(int fd)
 {
 	io_event *i;
-#ifdef IO_USE_SELECT
 	FD_CLR(fd, &writers);
 	FD_CLR(fd, &readers);
 
+	i = io_event_get(fd);
+	if (!i) return;
+
 	if (fd == select_maxfd) {
 		while (select_maxfd>0) {
-			--select_maxfd; /* find largest fd */  
+			--select_maxfd; /* find largest fd */
 			i = io_event_get(select_maxfd);
 			if (i && i->callback) break;
-		}	
-	}	
+		}
+	}
+}
+#else
+static inline void io_close_select(int UNUSED x) { /* NOTHING */ }
 #endif
+
+
+bool
+io_close(int fd)
+{
+	io_event *i;
+
 	i = io_event_get(fd);
 #ifdef IO_USE_KQUEUE
 	if (array_length(&io_evcache, sizeof (struct kevent)))	/* pending data in cache? */
@@ -385,8 +417,11 @@ io_close(int fd)
 	if (i) {
 		io_event_change_kqueue(fd, i->what, EV_DELETE);
 		io_event_kqueue_commit_cache();
-	}	
+	}
 #endif
+
+	io_close_select(fd);
+
 #ifdef IO_USE_EPOLL
 	io_event_change_epoll(fd, 0, EPOLL_CTL_DEL);
 #endif
@@ -516,7 +551,7 @@ io_dispatch_kqueue(struct timeval *tv)
 	int newevents_len;
 	ts.tv_sec = tv->tv_sec;
 	ts.tv_nsec = tv->tv_usec * 1000;
-	
+
 	do {
 		newevents_len = (int) array_length(&io_evcache, sizeof (struct kevent));
 		newevents = (newevents_len > 0) ? array_start(&io_evcache) : NULL;
@@ -541,10 +576,10 @@ io_dispatch_kqueue(struct timeval *tv)
 #ifdef DEBUG
 				LogDebug("kev.flag has EV_EOF set, setting IO_ERROR",
 					kev[i].filter, kev[i].ident);
-#endif				
+#endif
 				io_docallback((int)kev[i].ident, IO_ERROR);
 				continue;
-			}	
+			}
 
 			switch (kev[i].filter) {
 				case EVFILT_READ:
@@ -597,9 +632,9 @@ io_docallback(int fd, short what)
 #endif
 	i = io_event_get(fd);
 
-	if (i->callback) {	/* callback might be NULL if a previous callback function 
+	if (i->callback) {	/* callback might be NULL if a previous callback function
 				   called io_close on this fd */
 		i->callback(fd, (what & IO_ERROR) ? i->what : what);
-	}	
+	}
 	/* if error indicator is set, we return the event(s) that were registered */
 }