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

Contents of /pvpgn-1.7.4/src/common/fdwatch_poll.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 * poll(2) 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 #include "common/setup_before.h"
25 #ifdef STDC_HEADERS
26 # include <stdlib.h>
27 #else
28 # ifdef HAVE_MALLOC_H
29 # include <malloc.h>
30 # endif
31 #endif
32 #ifdef HAVE_STRING_H
33 # include <string.h>
34 #else
35 # ifdef HAVE_STRINGS_H
36 # include <strings.h>
37 # endif
38 #endif
39 #ifdef HAVE_POLL_H
40 # include <poll.h>
41 #else
42 # ifdef HAVE_SYS_POLL_H
43 # include <sys/poll.h>
44 # endif
45 #endif
46 #include "fdwatch.h"
47 #include "common/eventlog.h"
48 #include "common/xalloc.h"
49 #include "common/setup_after.h"
50
51 #ifdef HAVE_POLL
52 static int sr;
53 static struct pollfd *fds = NULL; /* working set */
54 static int *_rridx = NULL;
55 static int *_ridx = NULL;
56 static unsigned nofds;
57
58 static int fdw_poll_init(int nfds);
59 static int fdw_poll_close(void);
60 static int fdw_poll_add_fd(int idx, t_fdwatch_type rw);
61 static int fdw_poll_del_fd(int idx);
62 static int fdw_poll_watch(long timeout_msecs);
63 static void fdw_poll_handle(void);
64
65 t_fdw_backend fdw_poll = {
66 fdw_poll_init,
67 fdw_poll_close,
68 fdw_poll_add_fd,
69 fdw_poll_del_fd,
70 fdw_poll_watch,
71 fdw_poll_handle
72 };
73
74 static int fdw_poll_init(int nfds)
75 {
76 int i;
77
78 _ridx = xmalloc(sizeof(int) * nfds);
79 fds = xmalloc(sizeof(struct pollfd) * nfds);
80 _rridx = xmalloc(sizeof(int) * nfds);
81
82 memset(fds, 0, sizeof(struct pollfd) * nfds);
83 memset(_rridx, 0, sizeof(int) * nfds);
84 /* I would use a memset with 255 but that is dirty and doesnt gain us anything */
85 for(i = 0; i < nfds; i++) _ridx[i] = -1;
86 nofds = sr = 0;
87
88 eventlog(eventlog_level_info, __FUNCTION__, "fdwatch poll() based layer initialized (max %d sockets)", nfds);
89 return 0;
90 }
91
92 static int fdw_poll_close(void)
93 {
94 if (fds) { xfree((void *)fds); fds = NULL; }
95 if (_ridx) { xfree((void *)_ridx); _ridx = NULL; }
96 if (_rridx) { xfree((void *)_rridx); _rridx = NULL; }
97 nofds = sr = 0;
98
99 return 0;
100 }
101
102 static int fdw_poll_add_fd(int idx, t_fdwatch_type rw)
103 {
104 static int ridx;
105
106 // eventlog(eventlog_level_trace, __FUNCTION__, "called fd: %d rw: %d", fd, rw);
107 if (_ridx[idx] < 0) {
108 ridx = nofds++;
109 fds[ridx].fd = fdw_fd(fdw_fds + idx);
110 _ridx[idx] = ridx;
111 _rridx[ridx] = idx;
112 // eventlog(eventlog_level_trace, __FUNCTION__, "adding new fd on %d", ridx);
113 } else {
114 if (fds[_ridx[idx]].fd != fdw_fd(fdw_fds + idx)) {
115 eventlog(eventlog_level_error,__FUNCTION__,"BUG: found existent poll_fd entry for same idx with different fd");
116 return -1;
117 }
118 ridx = _ridx[idx];
119 // eventlog(eventlog_level_trace, __FUNCTION__, "updating fd on %d", ridx);
120 }
121
122 fds[ridx].events = 0;
123 if (rw & fdwatch_type_read) fds[ridx].events |= POLLIN;
124 if (rw & fdwatch_type_write) fds[ridx].events |= POLLOUT;
125
126 return 0;
127 }
128
129 static int fdw_poll_del_fd(int idx)
130 {
131 // eventlog(eventlog_level_trace, __FUNCTION__, "called fd: %d", fd);
132 if (_ridx[idx] < 0 || !nofds) return -1;
133 if (sr > 0)
134 eventlog(eventlog_level_error, __FUNCTION__, "BUG: called while still handling sockets");
135
136 /* move the last entry to the deleted one and decrement nofds count */
137 nofds--;
138 if (_ridx[idx] < nofds) {
139 // eventlog(eventlog_level_trace, __FUNCTION__, "not last, moving %d", tfds[nofds].fd);
140 _ridx[_rridx[nofds]] = _ridx[idx];
141 _rridx[_ridx[idx]] = _rridx[nofds];
142 memcpy(fds + _ridx[idx], fds + nofds, sizeof(struct pollfd));
143 }
144 _ridx[idx] = -1;
145
146 return 0;
147 }
148
149 static int fdw_poll_watch(long timeout_msec)
150 {
151 return (sr = poll(fds, nofds, timeout_msec));
152 }
153
154 static void fdw_poll_handle(void)
155 {
156 register unsigned i;
157 int changed;
158 t_fdwatch_fd *cfd;
159
160 for(i = 0; i < nofds && sr; i++) {
161 changed = 0;
162 cfd = fdw_fds + _rridx[i];
163
164 if (fdw_rw(cfd) & fdwatch_type_read &&
165 fds[i].revents & (POLLIN | POLLERR | POLLHUP | POLLNVAL))
166 {
167 if (fdw_hnd(cfd)(fdw_data(cfd), fdwatch_type_read) == -2) {
168 sr--;
169 continue;
170 }
171 changed = 1;
172 }
173
174 if (fdw_rw(cfd) & fdwatch_type_write &&
175 fds[i].revents & (POLLOUT | POLLERR | POLLHUP | POLLNVAL))
176 {
177 fdw_hnd(cfd)(fdw_data(cfd), fdwatch_type_write);
178 changed = 1;
179 }
180
181 if (changed) sr--;
182 }
183 }
184
185 #endif /* HAVE_POLL */

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