1 #include "config.h"
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <errno.h>
6 #ifdef WINDOWS
7 #include <winsock2.h>
8 #endif
9 #if defined HAVE_SYS_SELECT_H && !defined WINDOWS
10 /* because windows doesn't have it */
11 #include <sys/select.h>
12 #endif
13 //#include "pen.h"
14 #include "conn.h"
15 #include "diag.h"
16 #include "event.h"
17 
18 static fd_set w_read, w_write;
19 static fd_set w_r_copy, w_w_copy;
20 static int w_max;
21 
select_event_ctl(int fd,int events)22 static void select_event_ctl(int fd, int events)
23 {
24 	DEBUG(2, "select_event_ctl(fd=%d, events=%d)", fd, events);
25 	if (events & EVENT_READ) FD_SET(fd, &w_read);
26 	else FD_CLR(fd, &w_read);
27 	if (events & EVENT_WRITE) FD_SET(fd, &w_write);
28 	else FD_CLR(fd, &w_write);
29 	if (events) {
30 		if (fd >= w_max) w_max = fd+1;
31 	}
32 }
33 
select_event_add(int fd,int events)34 static void select_event_add(int fd, int events)
35 {
36 	DEBUG(2, "select_event_add(fd=%d, events=%d)", fd, events);
37 	select_event_ctl(fd, events);
38 }
39 
select_event_arm(int fd,int events)40 static void select_event_arm(int fd, int events)
41 {
42 	DEBUG(2, "select_event_arm(fd=%d, events=%d)", fd, events);
43 	select_event_ctl(fd, events);
44 }
45 
select_event_delete(int fd)46 static void select_event_delete(int fd)
47 {
48 	DEBUG(2, "select_event_delete(fd=%d)", fd);
49 	FD_CLR(fd, &w_read);
50 	FD_CLR(fd, &w_write);
51 }
52 
53 static int fd;
54 
select_event_wait(void)55 static void select_event_wait(void)
56 {
57 	int n, err;
58         struct timeval tv;
59 	DEBUG(2, "select_event_wait()");
60         tv.tv_sec = timeout;
61         tv.tv_usec = 0;
62 	memcpy(&w_r_copy, &w_read, sizeof w_read);
63 	memcpy(&w_w_copy, &w_write, sizeof w_write);
64 	fd = -1;
65         n = select(w_max, &w_r_copy, &w_w_copy, 0, &tv);
66 	err = socket_errno;
67 	DEBUG(2, "select returns %d, socket_errno=%d", n, err);
68         if (n < 0 && err != EINTR) {
69                 error("Error on select: %s", strerror(errno));
70         }
71 }
72 
select_event_fd(int * revents)73 static int select_event_fd(int *revents)
74 {
75         int events = 0;
76 	DEBUG(2, "select_event_fd(revents=%p)", revents);
77 	for (fd++; fd < w_max; fd++) {
78                 if (FD_ISSET(fd, &w_r_copy)) events |= EVENT_READ;
79                 if (FD_ISSET(fd, &w_w_copy)) events |= EVENT_WRITE;
80                 if (events) {
81 			*revents = events;
82 			return fd;
83 		}
84         }
85         return -1;
86 }
87 
select_init(void)88 void select_init(void)
89 {
90 	DEBUG(2, "select_init()");
91 	if ((connections_max*2+10) > FD_SETSIZE) {
92 		error("Number of simultaneous connections too large.\n"
93 			"Maximum is %d, or re-build pen with larger FD_SETSIZE",
94 			(FD_SETSIZE-10)/2);
95 	}
96 	FD_ZERO(&w_read);
97 	FD_ZERO(&w_write);
98 	w_max = 0;
99 	event_add = select_event_add;
100 	event_arm = select_event_arm;
101 	event_delete = select_event_delete;
102 	event_wait = select_event_wait;
103 	event_fd = select_event_fd;
104 }
105 
106