/[LeafOK_CVS]/pvpgn-1.7.4/src/common/fdwatch_select.c
ViewVC logotype

Contents of /pvpgn-1.7.4/src/common/fdwatch_select.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (show annotations) (vendor branch)
Tue Jun 6 03:41:38 2006 UTC (19 years, 9 months ago) by sysadm
Branch: GNU, MAIN
CVS Tags: arelease, HEAD
Changes since 1.1: +0 -0 lines
Content type: text/x-csrc
no message

1 /*
2 * Abstraction API/layer for the various ways PvPGN can inspect sockets state
3 * 2003 (C) dizzy@roedu.net
4 *
5 * Code is based on the ideas found in thttpd project.
6 *
7 * select() based backend
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24 #define FDWATCH_BACKEND
25 #include "common/setup_before.h"
26 #ifdef STDC_HEADERS
27 # include <stdlib.h>
28 #else
29 # ifdef HAVE_MALLOC_H
30 # include <malloc.h>
31 # endif
32 #endif
33 #ifdef HAVE_STRING_H
34 # include <string.h>
35 #else
36 # ifdef HAVE_STRINGS_H
37 # include <strings.h>
38 # endif
39 #endif
40 /* According to earlier standards */
41 #ifdef HAVE_SYS_TIME_H
42 # include <sys/time.h>
43 #endif
44 #ifdef HAVE_SYS_TYPES_H
45 # include <sys/types.h>
46 #endif
47 #ifdef HAVE_UNISTD_H
48 # include <unistd.h>
49 #endif
50 /* According to POSIX 1003.1-2001 */
51 #ifdef HAVE_SYS_SELECT_H
52 # include <sys/select.h>
53 #endif
54 #include "compat/psock.h"
55 #include "fdwatch.h"
56 #include "common/eventlog.h"
57 #include "common/xalloc.h"
58 #include "common/elist.h"
59 #include "common/setup_after.h"
60
61 #ifdef HAVE_SELECT
62
63 static int sr;
64 static int smaxfd;
65 static t_psock_fd_set *rfds = NULL, *wfds = NULL, /* working sets (updated often) */
66 *trfds = NULL, *twfds = NULL; /* templates (updated rare) */
67
68 static int fdw_select_init(int nfds);
69 static int fdw_select_close(void);
70 static int fdw_select_add_fd(int idx, t_fdwatch_type rw);
71 static int fdw_select_del_fd(int idx);
72 static int fdw_select_watch(long timeout_msecs);
73 static void fdw_select_handle(void);
74
75 t_fdw_backend fdw_select = {
76 fdw_select_init,
77 fdw_select_close,
78 fdw_select_add_fd,
79 fdw_select_del_fd,
80 fdw_select_watch,
81 fdw_select_handle
82 };
83
84 static int fdw_select_init(int nfds)
85 {
86 if (nfds > FD_SETSIZE) return -1; /* this should not happen */
87
88 rfds = xmalloc(sizeof(t_psock_fd_set));
89 wfds = xmalloc(sizeof(t_psock_fd_set));
90 trfds = xmalloc(sizeof(t_psock_fd_set));
91 twfds = xmalloc(sizeof(t_psock_fd_set));
92
93 PSOCK_FD_ZERO(trfds); PSOCK_FD_ZERO(twfds);
94 smaxfd = sr = 0;
95
96 eventlog(eventlog_level_info, __FUNCTION__, "fdwatch select() based layer initialized (max %d sockets)", nfds);
97 return 0;
98 }
99
100 static int fdw_select_close(void)
101 {
102 if (rfds) { xfree((void *)rfds); rfds = NULL; }
103 if (wfds) { xfree((void *)wfds); wfds = NULL; }
104 if (trfds) { xfree((void *)trfds); trfds = NULL; }
105 if (twfds) { xfree((void *)twfds); twfds = NULL; }
106 smaxfd = sr = 0;
107
108 return 0;
109 }
110
111 static int fdw_select_add_fd(int idx, t_fdwatch_type rw)
112 {
113 int fd;
114
115 // eventlog(eventlog_level_trace, __FUNCTION__, "called fd: %d rw: %d", fd, rw);
116 fd = fdw_fd(fdw_fds + idx);
117
118 /* select() interface is limited by FD_SETSIZE max socket value */
119 if (fd >= FD_SETSIZE) return -1;
120
121 if (rw & fdwatch_type_read) PSOCK_FD_SET(fd, trfds);
122 else PSOCK_FD_CLR(fd, trfds);
123 if (rw & fdwatch_type_write) PSOCK_FD_SET(fd, twfds);
124 else PSOCK_FD_CLR(fd, twfds);
125 if (smaxfd < fd) smaxfd = fd;
126
127 return 0;
128 }
129
130 static int fdw_select_del_fd(int idx)
131 {
132 int fd;
133
134 fd = fdw_fd(fdw_fds + idx);
135 // eventlog(eventlog_level_trace, __FUNCTION__, "called fd: %d", fd);
136 if (sr > 0)
137 eventlog(eventlog_level_error, __FUNCTION__, "BUG: called while still handling sockets");
138 PSOCK_FD_CLR(fd, trfds);
139 PSOCK_FD_CLR(fd, twfds);
140
141 return 0;
142 }
143
144 static int fdw_select_watch(long timeout_msec)
145 {
146 static struct timeval tv;
147
148 tv.tv_sec = timeout_msec / 1000;
149 tv.tv_usec = timeout_msec % 1000;
150
151 /* set the working sets based on the templates */
152 memcpy(rfds, trfds, sizeof(t_psock_fd_set));
153 memcpy(wfds, twfds, sizeof(t_psock_fd_set));
154
155 return (sr = psock_select(smaxfd + 1, rfds, wfds, NULL, &tv));
156 }
157
158 static int fdw_select_cb(t_fdwatch_fd *cfd, void *data)
159 {
160 // eventlog(eventlog_level_trace, __FUNCTION__, "idx: %d fd: %d", idx, fdw_fd->fd);
161 if (fdw_rw(cfd) & fdwatch_type_read && PSOCK_FD_ISSET(fdw_fd(cfd), rfds)
162 && fdw_hnd(cfd)(fdw_data(cfd), fdwatch_type_read) == -2) return 0;
163 if (fdw_rw(cfd) & fdwatch_type_write && PSOCK_FD_ISSET(fdw_fd(cfd), wfds))
164 fdw_hnd(cfd)(fdw_data(cfd), fdwatch_type_write);
165
166 return 0;
167 }
168
169 static void fdw_select_handle(void)
170 {
171 // eventlog(eventlog_level_trace, __FUNCTION__, "called nofds: %d", fdw_nofds);
172 fdwatch_traverse(fdw_select_cb,NULL);
173 sr = 0;
174 }
175
176 #endif /* HAVE_SELECT */

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1