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

Annotation of /pvpgn-1.7.4/src/common/fdwatch_poll.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations)
Tue Jun 6 03:41:38 2006 UTC (19 years, 9 months ago) by sysadm
CVS Tags: pvpgn_1-7-4-0_MIL
Branch point for: GNU, MAIN
Content type: text/x-csrc
Initial revision

1 sysadm 1.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