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

Annotation of /pvpgn-1.7.4/src/common/fdwatch_epoll.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     * Linux epoll(4) 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 HAVE_EPOLL
26    
27     #ifdef STDC_HEADERS
28     # include <stdlib.h>
29     #else
30     # ifdef HAVE_MALLOC_H
31     # include <malloc.h>
32     # endif
33     #endif
34     #ifdef HAVE_STRING_H
35     # include <string.h>
36     #else
37     # ifdef HAVE_STRINGS_H
38     # include <strings.h>
39     # endif
40     #endif
41     #ifdef HAVE_SYS_EPOLL_H
42     # include "compat/uint.h"
43     # include <sys/epoll.h>
44     #endif
45     #include "fdwatch.h"
46     #include "common/eventlog.h"
47     #include "common/xalloc.h"
48     #include "common/setup_after.h"
49    
50     static int sr;
51     static int epfd;
52     static struct epoll_event *epevents = NULL; /* events to investigate */
53     static struct epoll_event tmpev;
54    
55     static int fdw_epoll_init(int nfds);
56     static int fdw_epoll_close(void);
57     static int fdw_epoll_add_fd(int idx, t_fdwatch_type rw);
58     static int fdw_epoll_del_fd(int idx);
59     static int fdw_epoll_watch(long timeout_msecs);
60     static void fdw_epoll_handle(void);
61    
62     t_fdw_backend fdw_epoll = {
63     fdw_epoll_init,
64     fdw_epoll_close,
65     fdw_epoll_add_fd,
66     fdw_epoll_del_fd,
67     fdw_epoll_watch,
68     fdw_epoll_handle
69     };
70    
71     static int fdw_epoll_init(int nfds)
72     {
73     if ((epfd = epoll_create(nfds)) < 0)
74     return -1;
75     epevents = (struct epoll_event *) xmalloc(sizeof(struct epoll_event) * nfds);
76    
77     memset(epevents, 0, sizeof(struct epoll_event) * nfds);
78     sr = 0;
79    
80     eventlog(eventlog_level_info, __FUNCTION__, "fdwatch epoll() based layer initialized (max %d sockets)", nfds);
81     return 0;
82     }
83    
84     static int fdw_epoll_close(void)
85     {
86     if (epevents != NULL)
87     xfree((void *) epevents);
88     sr = 0;
89    
90     return 0;
91     }
92    
93     static int fdw_epoll_add_fd(int idx, t_fdwatch_type rw)
94     {
95     int op;
96     // eventlog(eventlog_level_trace, __FUNCTION__, "called fd: %d rw: %d", fd, rw);
97    
98     tmpev.events = 0;
99     if (rw & fdwatch_type_read)
100     tmpev.events |= EPOLLIN;
101     if (rw & fdwatch_type_write)
102     tmpev.events |= EPOLLOUT;
103    
104     if (fdw_rw(fdw_fds + idx)) op = EPOLL_CTL_MOD;
105     else op = EPOLL_CTL_ADD;
106    
107     tmpev.data.fd = idx;
108     if (epoll_ctl(epfd, op, fdw_fd(fdw_fds + idx), &tmpev)) {
109     eventlog(eventlog_level_error, __FUNCTION__, "got error from epoll_ctl()");
110     return -1;
111     }
112    
113     return 0;
114     }
115    
116     static int fdw_epoll_del_fd(int idx)
117     {
118     // eventlog(eventlog_level_trace, __FUNCTION__, "called fd: %d", fd);
119     if (sr > 0)
120     eventlog(eventlog_level_error, __FUNCTION__, "BUG: called while still handling sockets");
121    
122     if (fdw_rw(fdw_fds + idx)) {
123     tmpev.events = 0;
124     tmpev.data.fd = idx;
125     if (epoll_ctl(epfd, EPOLL_CTL_DEL, fdw_fd(fdw_fds + idx), &tmpev)) {
126     eventlog(eventlog_level_error, __FUNCTION__, "got error from epoll_ctl()");
127     return -1;
128     }
129     }
130    
131     return 0;
132     }
133    
134     static int fdw_epoll_watch(long timeout_msec)
135     {
136     return (sr = epoll_wait(epfd, epevents, fdw_maxcons, timeout_msec));
137     }
138    
139     static void fdw_epoll_handle(void)
140     {
141     struct epoll_event *ev;
142     t_fdwatch_fd *cfd;
143    
144     // eventlog(eventlog_level_trace, __FUNCTION__, "called");
145     for (ev = epevents; sr; sr--, ev++)
146     {
147     // eventlog(eventlog_level_trace, __FUNCTION__, "checking %d ident: %d read: %d write: %d", i, kqevents[i].ident, kqevents[i].filter & EVFILT_READ, kqevents[i].filter & EVFILT_WRITE);
148     cfd = fdw_fds + ev->data.fd;
149    
150     if (fdw_rw(cfd) & fdwatch_type_read && ev->events & (EPOLLIN | EPOLLERR | EPOLLHUP))
151     if (fdw_hnd(cfd) (fdw_data(cfd), fdwatch_type_read) == -2)
152     continue;
153    
154     if (fdw_rw(cfd) & fdwatch_type_write && ev->events & (EPOLLOUT | EPOLLERR | EPOLLHUP))
155     fdw_hnd(cfd) (fdw_data(cfd), fdwatch_type_write);
156     }
157     sr = 0;
158     }
159    
160     #endif /* HAVE_EPOLL */

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