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