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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (hide 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 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     * 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