ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/s_bsd_kqueue.c
Revision: 4565
Committed: Sun Aug 24 10:27:40 2014 UTC (9 years, 7 months ago) by michael
Content type: text/x-csrc
File size: 4711 byte(s)
Log Message:
- Update GPL 2 license headers

File Contents

# User Rev Content
1 adx 30 /*
2 michael 2916 * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3 adx 30 *
4 michael 2916 * Copyright (c) 2000-2014 ircd-hybrid development team
5 adx 30 *
6     * This program is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18 michael 4565 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19 adx 30 * USA
20     */
21    
22 michael 2916 /*! \file s_bsd_kqueue.c
23     * \brief kqueue() compatible network routines.
24     * \version $Id$
25     */
26    
27 adx 30 #include "stdinc.h"
28 stu 908 #if USE_IOPOLL_MECHANISM == __IOPOLL_MECHANISM_KQUEUE
29 adx 30 #include <sys/event.h>
30     #include "fdlist.h"
31     #include "ircd.h"
32     #include "s_bsd.h"
33 michael 1309 #include "log.h"
34 adx 30
35     #define KE_LENGTH 128
36    
37     static fde_t kqfd;
38     static struct kevent kq_fdlist[KE_LENGTH]; /* kevent buffer */
39     static int kqoff; /* offset into the buffer */
40    
41 michael 3984
42 adx 30 /*
43     * init_netio
44     *
45     * This is a needed exported function which will be called to initialise
46     * the network loop code.
47     */
48     void
49     init_netio(void)
50     {
51     int fd;
52    
53     if ((fd = kqueue()) < 0)
54     {
55 michael 1247 ilog(LOG_TYPE_IRCD, "init_netio: Couldn't open kqueue fd!");
56 adx 30 exit(115); /* Whee! */
57     }
58    
59     fd_open(&kqfd, fd, 0, "kqueue() file descriptor");
60     }
61    
62     /*
63     * Write a single update to the kqueue list.
64     */
65     static void
66     kq_update_events(int fd, int filter, int what)
67     {
68     static struct timespec zero_timespec = {0, 0};
69     struct kevent *kep = kq_fdlist + kqoff;
70    
71     EV_SET(kep, (uintptr_t) fd, (short) filter, what, 0, 0, NULL);
72    
73 adx 842 if (++kqoff == KE_LENGTH)
74 adx 30 {
75 michael 2589 int i;
76    
77     for (i = 0; i < kqoff; ++i)
78 michael 2613 kevent(kqfd.fd, &kq_fdlist[i], 1, NULL, 0, &zero_timespec);
79 adx 30 kqoff = 0;
80     }
81     }
82    
83     /*
84     * comm_setselect
85     *
86     * This is a needed exported function which will be called to register
87     * and deregister interest in a pending IO state for a given FD.
88     */
89     void
90 michael 4461 comm_setselect(fde_t *F, unsigned int type, void (*handler)(fde_t *, void *),
91 adx 30 void *client_data, time_t timeout)
92     {
93     int new_events, diff;
94    
95     if ((type & COMM_SELECT_READ))
96     {
97     F->read_handler = handler;
98     F->read_data = client_data;
99     }
100    
101     if ((type & COMM_SELECT_WRITE))
102     {
103     F->write_handler = handler;
104     F->write_data = client_data;
105     }
106    
107     new_events = (F->read_handler ? COMM_SELECT_READ : 0) |
108 michael 2650 (F->write_handler ? COMM_SELECT_WRITE : 0);
109 adx 30
110     if (timeout != 0)
111 michael 2725 {
112 adx 30 F->timeout = CurrentTime + (timeout / 1000);
113 michael 2725 F->timeout_handler = handler;
114     F->timeout_data = client_data;
115     }
116 adx 30
117     diff = new_events ^ F->evcache;
118    
119     if ((diff & COMM_SELECT_READ))
120     kq_update_events(F->fd, EVFILT_READ,
121     (new_events & COMM_SELECT_READ) ? EV_ADD : EV_DELETE);
122     if ((diff & COMM_SELECT_WRITE))
123     kq_update_events(F->fd, EVFILT_WRITE,
124     (new_events & COMM_SELECT_WRITE) ? EV_ADD : EV_DELETE);
125    
126     F->evcache = new_events;
127     }
128    
129     /*
130     * comm_select
131     *
132     * Called to do the new-style IO, courtesy of squid (like most of this
133     * new IO code). This routine handles the stuff we've hidden in
134     * comm_setselect and fd_table[] and calls callbacks for IO ready
135     * events.
136     */
137     void
138     comm_select(void)
139     {
140     int num, i;
141     static struct kevent ke[KE_LENGTH];
142     struct timespec poll_time;
143 michael 4461 void (*hdl)(fde_t *, void *);
144 adx 30 fde_t *F;
145    
146     /*
147     * remember we are doing NANOseconds here, not micro/milli. God knows
148     * why jlemon used a timespec, but hey, he wrote the interface, not I
149     * -- Adrian
150     */
151     poll_time.tv_sec = 0;
152     poll_time.tv_nsec = SELECT_DELAY * 1000000;
153     num = kevent(kqfd.fd, kq_fdlist, kqoff, ke, KE_LENGTH, &poll_time);
154     kqoff = 0;
155    
156     set_time();
157    
158     if (num < 0)
159     {
160     #ifdef HAVE_USLEEP
161     usleep(50000); /* avoid 99% CPU in comm_select */
162     #endif
163     return;
164     }
165    
166     for (i = 0; i < num; i++)
167     {
168     F = lookup_fd(ke[i].ident);
169     if (F == NULL || !F->flags.open || (ke[i].flags & EV_ERROR))
170     continue;
171    
172     if (ke[i].filter == EVFILT_READ)
173 michael 2650 {
174 adx 30 if ((hdl = F->read_handler) != NULL)
175     {
176     F->read_handler = NULL;
177     hdl(F, F->read_data);
178 michael 2614 if (!F->flags.open)
179     continue;
180 adx 30 }
181 michael 2650 }
182 adx 30
183     if (ke[i].filter == EVFILT_WRITE)
184 michael 2650 {
185 adx 30 if ((hdl = F->write_handler) != NULL)
186     {
187     F->write_handler = NULL;
188     hdl(F, F->write_data);
189 michael 2614 if (!F->flags.open)
190     continue;
191 adx 30 }
192 michael 2650 }
193 adx 30
194     comm_setselect(F, 0, NULL, NULL, 0);
195     }
196     }
197 stu 908 #endif

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision