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

Contents of /pvpgn-1.7.4/src/common/fdwatch_epoll.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 * 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