1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
|
.TH "SocketEngine" 3 "14 Dec 2005" "Version 1.0Betareleases" "InspIRCd" \" -*- nroff -*-
.ad l
.nh
.SH NAME
SocketEngine \- The actual socketengine class presents the same interface on all operating systems, but its private members and internal behaviour should be treated as blackboxed, and vary from system to system and upon the config settings chosen by the server admin.
.PP
.SH SYNOPSIS
.br
.PP
\fC#include <socketengine.h>\fP
.PP
.SS "Public Member Functions"
.in +1c
.ti -1c
.RI "\fBSocketEngine\fP ()"
.br
.RI "\fIConstructor The constructor transparently initializes the socket engine which the ircd is using. \fP"
.ti -1c
.RI "\fB~SocketEngine\fP ()"
.br
.RI "\fIDestructor The destructor transparently tidies up any resources used by the socket engine. \fP"
.ti -1c
.RI "bool \fBAddFd\fP (int fd, bool readable, char type)"
.br
.RI "\fIAdd a file descriptor to the engine Use AddFd to add a file descriptor to the engine and have the socket engine monitor it. \fP"
.ti -1c
.RI "char \fBGetType\fP (int fd)"
.br
.RI "\fIReturns the type value for this file descriptor This function masks off the X_READBIT value so that the type of the socket can be obtained. \fP"
.ti -1c
.RI "bool \fBDelFd\fP (int fd)"
.br
.RI "\fIDelete a file descriptor f rom the engine This function call deletes a file descriptor from the engine, returning true if it succeeded and false if it failed. \fP"
.ti -1c
.RI "bool \fBWait\fP (std::vector< int > &fdlist)"
.br
.RI "\fIWaits for an event. \fP"
.ti -1c
.RI "\fBstd::string\fP \fBGetName\fP ()"
.br
.RI "\fIReturns the socket engines name This returns the name of the engine for use in /VERSION responses. \fP"
.in -1c
.SS "Private Attributes"
.in +1c
.ti -1c
.RI "std::vector< int > \fBfds\fP"
.br
.ti -1c
.RI "int \fBEngineHandle\fP"
.br
.ti -1c
.RI "kevent \fBke_list\fP [65535]"
.br
.ti -1c
.RI "timespec \fBts\fP"
.br
.in -1c
.SH "Detailed Description"
.PP
The actual socketengine class presents the same interface on all operating systems, but its private members and internal behaviour should be treated as blackboxed, and vary from system to system and upon the config settings chosen by the server admin.
The current version supports select, epoll and kqueue.
.PP
Definition at line 66 of file socketengine.h.
.SH "Constructor & Destructor Documentation"
.PP
.SS "SocketEngine::SocketEngine ()"
.PP
Constructor The constructor transparently initializes the socket engine which the ircd is using.
.PP
Please note that if there is a catastrophic failure (for example, you try and enable epoll on a 2.4 linux kernel) then this function may bail back to the shell.
.PP
Definition at line 35 of file socketengine.cpp.
.PP
References DEBUG, EngineHandle, and log().
.PP
.nf
36 {
37 log(DEBUG,'SocketEngine::SocketEngine()');
38 #ifdef USE_EPOLL
39 EngineHandle = epoll_create(65535);
40 #endif
41 #ifdef USE_KQUEUE
42 EngineHandle = kqueue();
43 #endif
44 }
.fi
.PP
.SS "SocketEngine::~SocketEngine ()"
.PP
Destructor The destructor transparently tidies up any resources used by the socket engine.
.PP
Definition at line 46 of file socketengine.cpp.
.PP
References DEBUG, EngineHandle, and log().
.PP
.nf
47 {
48 log(DEBUG,'SocketEngine::~SocketEngine()');
49 #ifdef USE_EPOLL
50 close(EngineHandle);
51 #endif
52 #ifdef USE_KQUEUE
53 close(EngineHandle);
54 #endif
55 }
.fi
.PP
.SH "Member Function Documentation"
.PP
.SS "bool SocketEngine::AddFd (int fd, bool readable, char type)"
.PP
Add a file descriptor to the engine Use AddFd to add a file descriptor to the engine and have the socket engine monitor it.
.PP
You must provide a type (see the consts in \fBsocketengine.h\fP) and a boolean flag to indicate wether to watch this fd for read or write events (there is currently no need for support of both).
.PP
Definition at line 65 of file socketengine.cpp.
.PP
References DEBUG, EngineHandle, fds, log(), ref, and X_READBIT.
.PP
Referenced by InspSocket::InspSocket(), and InspSocket::Poll().
.PP
.nf
66 {
67 if ((fd < 0) || (fd > 65535))
68 return false;
69 this->fds.push_back(fd);
70 ref[fd] = type;
71 if (readable)
72 {
73 log(DEBUG,'Set readbit');
74 ref[fd] |= X_READBIT;
75 }
76 log(DEBUG,'Add socket %d',fd);
77 #ifdef USE_EPOLL
78 struct epoll_event ev;
79 log(DEBUG,'epoll: Add socket to events, ep=%d socket=%d',EngineHandle,fd);
80 readable ? ev.events = EPOLLIN | EPOLLET : ev.events = EPOLLOUT | EPOLLET;
81 ev.data.fd = fd;
82 int i = epoll_ctl(EngineHandle, EPOLL_CTL_ADD, fd, &ev);
83 if (i < 0)
84 {
85 log(DEBUG,'epoll: List insertion failure!');
86 return false;
87 }
88 #endif
89 #ifdef USE_KQUEUE
90 struct kevent ke;
91 log(DEBUG,'kqueue: Add socket to events, kq=%d socket=%d',EngineHandle,fd);
92 EV_SET(&ke, fd, readable ? EVFILT_READ : EVFILT_WRITE, EV_ADD, 0, 0, NULL);
93 int i = kevent(EngineHandle, &ke, 1, 0, 0, NULL);
94 if (i == -1)
95 {
96 log(DEBUG,'kqueue: List insertion failure!');
97 return false;
98 }
99 #endif
100 return true;
101 }
.fi
.PP
.SS "bool SocketEngine::DelFd (int fd)"
.PP
Delete a file descriptor f rom the engine This function call deletes a file descriptor from the engine, returning true if it succeeded and false if it failed.
.PP
Definition at line 103 of file socketengine.cpp.
.PP
References DEBUG, EngineHandle, fds, log(), ref, and X_READBIT.
.PP
Referenced by InspSocket::Poll(), and Server::UserToPseudo().
.PP
.nf
104 {
105 log(DEBUG,'SocketEngine::DelFd(%d)',fd);
106
107 if ((fd < 0) || (fd > 65535))
108 return false;
109
110 bool found = false;
111 for (std::vector<int>::iterator i = fds.begin(); i != fds.end(); i++)
112 {
113 if (*i == fd)
114 {
115 fds.erase(i);
116 log(DEBUG,'Deleted fd %d',fd);
117 found = true;
118 break;
119 }
120 }
121 #ifdef USE_KQUEUE
122 struct kevent ke;
123 EV_SET(&ke, fd, ref[fd] & X_READBIT ? EVFILT_READ : EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
124 int i = kevent(EngineHandle, &ke, 1, 0, 0, NULL);
125 if (i == -1)
126 {
127 log(DEBUG,'kqueue: Failed to remove socket from queue!');
128 return false;
129 }
130 #endif
131 #ifdef USE_EPOLL
132 struct epoll_event ev;
133 ref[fd] && X_READBIT ? ev.events = EPOLLIN | EPOLLET : ev.events = EPOLLOUT | EPOLLET;
134 ev.data.fd = fd;
135 int i = epoll_ctl(EngineHandle, EPOLL_CTL_DEL, fd, &ev);
136 if (i < 0)
137 {
138 log(DEBUG,'epoll: List deletion failure!');
139 return false;
140 }
141 #endif
142 ref[fd] = 0;
143 return found;
144 }
.fi
.PP
.SS "\fBstd::string\fP SocketEngine::GetName ()"
.PP
Returns the socket engines name This returns the name of the engine for use in /VERSION responses.
.PP
Definition at line 193 of file socketengine.cpp.
.PP
.nf
194 {
195 #ifdef USE_SELECT
196 return 'select';
197 #endif
198 #ifdef USE_KQUEUE
199 return 'kqueue';
200 #endif
201 #ifdef USE_EPOLL
202 return 'epoll';
203 #endif
204 return 'misconfigured';
205 }
.fi
.PP
.SS "char SocketEngine::GetType (int fd)"
.PP
Returns the type value for this file descriptor This function masks off the X_READBIT value so that the type of the socket can be obtained.
.PP
The core uses this to decide where to dispatch the event to. Please note that some engines such as select() have an upper limit of 1024 descriptors which may be active at any one time, where others such as kqueue have no practical limits at all.
.PP
Definition at line 57 of file socketengine.cpp.
.PP
References ref, and X_EMPTY_SLOT.
.PP
.nf
58 {
59 if ((fd < 0) || (fd > 65535))
60 return X_EMPTY_SLOT;
61 /* Mask off the top bit used for 'read/write' state */
62 return (ref[fd] & ~0x80);
63 }
.fi
.PP
.SS "bool SocketEngine::Wait (std::vector< int > & fdlist)"
.PP
Waits for an event.
.PP
Please note that this doesnt wait long, only a couple of milliseconds. It returns a list of active file descriptors in the vector fdlist which the core may then act upon.
.PP
Definition at line 146 of file socketengine.cpp.
.PP
References EngineHandle, fds, ke_list, ref, ts, and X_READBIT.
.PP
.nf
147 {
148 fdlist.clear();
149 #ifdef USE_SELECT
150 FD_ZERO(&wfdset);
151 FD_ZERO(&rfdset);
152 timeval tval;
153 int sresult;
154 for (unsigned int a = 0; a < fds.size(); a++)
155 {
156 if (ref[fds[a]] & X_READBIT)
157 {
158 FD_SET (fds[a], &rfdset);
159 }
160 else
161 {
162 FD_SET (fds[a], &wfdset);
163 }
164
165 }
166 tval.tv_sec = 0;
167 tval.tv_usec = 100L;
168 sresult = select(FD_SETSIZE, &rfdset, &wfdset, NULL, &tval);
169 if (sresult > 0)
170 {
171 for (unsigned int a = 0; a < fds.size(); a++)
172 {
173 if ((FD_ISSET (fds[a], &rfdset)) || (FD_ISSET (fds[a], &wfdset)))
174 fdlist.push_back(fds[a]);
175 }
176 }
177 #endif
178 #ifdef USE_KQUEUE
179 ts.tv_nsec = 10000L;
180 ts.tv_sec = 0;
181 int i = kevent(EngineHandle, NULL, 0, &ke_list[0], 65535, &ts);
182 for (int j = 0; j < i; j++)
183 fdlist.push_back(ke_list[j].ident);
184 #endif
185 #ifdef USE_EPOLL
186 int i = epoll_wait(EngineHandle, events, 65535, 100);
187 for (int j = 0; j < i; j++)
188 fdlist.push_back(events[j].data.fd);
189 #endif
190 return true;
191 }
.fi
.PP
.SH "Member Data Documentation"
.PP
.SS "int \fBSocketEngine::EngineHandle\fP\fC [private]\fP"
.PP
Definition at line 69 of file socketengine.h.
.PP
Referenced by AddFd(), DelFd(), SocketEngine(), Wait(), and ~SocketEngine().
.SS "std::vector<int> \fBSocketEngine::fds\fP\fC [private]\fP"
.PP
Definition at line 68 of file socketengine.h.
.PP
Referenced by AddFd(), DelFd(), and Wait().
.SS "struct kevent \fBSocketEngine::ke_list\fP[65535]\fC [private]\fP"
.PP
Definition at line 74 of file socketengine.h.
.PP
Referenced by Wait().
.SS "struct timespec \fBSocketEngine::ts\fP\fC [private]\fP"
.PP
Definition at line 75 of file socketengine.h.
.PP
Referenced by Wait().
.SH "Author"
.PP
Generated automatically by Doxygen for InspIRCd from the source code.
|