]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/socketengine.cpp
Changed some little bits and bobs here
[user/henk/code/inspircd.git] / src / socketengine.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  Inspire is copyright (C) 2002-2005 ChatSpike-Dev.
6  *                       E-mail:
7  *                <brain@chatspike.net>
8  *                <Craig@chatspike.net>
9  *
10  * Written by Craig Edwards, Craig McLure, and others.
11  * This program is free but copyrighted software; see
12  *            the file COPYING for details.
13  *
14  * ---------------------------------------------------
15  */
16
17 #include "inspircd_config.h"
18 #include "globals.h"
19 #include "inspircd.h"
20 #ifdef USE_EPOLL
21 #include <sys/epoll.h>
22 #define EP_DELAY 5
23 #endif
24 #ifdef USE_KQUEUE
25 #include <sys/types.h>
26 #include <sys/event.h>
27 #include <sys/time.h>
28 #endif
29 #include <vector>
30 #include <string>
31 #include "socketengine.h"
32
33 char ref[65535];
34
35 SocketEngine::SocketEngine()
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 }
45
46 SocketEngine::~SocketEngine()
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 }
56
57 char SocketEngine::GetType(int fd)
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 }
64
65 bool SocketEngine::AddFd(int fd, bool readable, char type)
66 {
67         if ((fd < 0) || (fd > 65535))
68                 return false;
69 #ifdef USE_SELECT
70         fds[fd] = fd;
71 #endif
72         ref[fd] = type;
73         if (readable)
74         {
75                 log(DEBUG,"Set readbit");
76                 ref[fd] |= X_READBIT;
77         }
78         log(DEBUG,"Add socket %d",fd);
79 #ifdef USE_EPOLL
80         struct epoll_event ev;
81         log(DEBUG,"epoll: Add socket to events, ep=%d socket=%d",EngineHandle,fd);
82         readable ? ev.events = EPOLLIN | EPOLLET : ev.events = EPOLLOUT | EPOLLET;
83         ev.data.fd = fd;
84         int i = epoll_ctl(EngineHandle, EPOLL_CTL_ADD, fd, &ev);
85         if (i < 0)
86         {
87                 log(DEBUG,"epoll: List insertion failure!");
88                 return false;
89         }
90 #endif
91 #ifdef USE_KQUEUE
92         struct kevent ke;
93         log(DEBUG,"kqueue: Add socket to events, kq=%d socket=%d",EngineHandle,fd);
94         EV_SET(&ke, fd, readable ? EVFILT_READ : EVFILT_WRITE, EV_ADD, 0, 0, NULL);
95         int i = kevent(EngineHandle, &ke, 1, 0, 0, NULL);
96         if (i == -1)
97         {
98                 log(DEBUG,"kqueue: List insertion failure!");
99                 return false;
100         }
101 #endif
102 return true;
103 }
104
105 bool SocketEngine::DelFd(int fd)
106 {
107         log(DEBUG,"SocketEngine::DelFd(%d)",fd);
108
109         if ((fd < 0) || (fd > 65535))
110                 return false;
111
112 #ifdef USE_SELECT
113         std::map<int,int>::iterator t = fds.find(fd);
114         if (t != fds.end())
115         {
116                 fds.erase(t);
117                 log(DEBUG,"Deleted fd %d",fd);
118         }
119 #endif
120 #ifdef USE_KQUEUE
121         struct kevent ke;
122         EV_SET(&ke, fd, ref[fd] & X_READBIT ? EVFILT_READ : EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
123         int i = kevent(EngineHandle, &ke, 1, 0, 0, NULL);
124         if (i == -1)
125         {
126                 log(DEBUG,"kqueue: Failed to remove socket from queue!");
127                 return false;
128         }
129 #endif
130 #ifdef USE_EPOLL
131         struct epoll_event ev;
132         ref[fd] && X_READBIT ? ev.events = EPOLLIN | EPOLLET : ev.events = EPOLLOUT | EPOLLET;
133         ev.data.fd = fd;
134         int i = epoll_ctl(EngineHandle, EPOLL_CTL_DEL, fd, &ev);
135         if (i < 0)
136         {
137                 log(DEBUG,"epoll: List deletion failure!");
138                 return false;
139         }
140 #endif
141         ref[fd] = 0;
142         return true;
143 }
144
145 int SocketEngine::Wait(int* fdlist)
146 {
147         int result = 0;
148 #ifdef USE_SELECT
149         FD_ZERO(&wfdset);
150         FD_ZERO(&rfdset);
151         timeval tval;
152         int sresult;
153         for (std::map<int,int>::iterator a = fds.begin(); a != fds.end(); a++)
154         {
155                 if (ref[a->second] & X_READBIT)
156                 {
157                         FD_SET (a->second, &rfdset);
158                 }
159                 else
160                 {
161                         FD_SET (a->second, &wfdset);
162                 }
163                 
164         }
165         tval.tv_sec = 0;
166         tval.tv_usec = 100L;
167         sresult = select(FD_SETSIZE, &rfdset, &wfdset, NULL, &tval);
168         if (sresult > 0)
169         {
170                 for (std::map<int,int>::iterator a = fds.begin(); a != fds.end(); a++)
171                 {
172                         if ((FD_ISSET (a->second, &rfdset)) || (FD_ISSET (a->second, &wfdset)))
173                                 fdlist[result++] = a->second;
174                 }
175         }
176 #endif
177 #ifdef USE_KQUEUE
178         ts.tv_nsec = 10000L;
179         ts.tv_sec = 0;
180         int i = kevent(EngineHandle, NULL, 0, &ke_list[0], 65535, &ts);
181         for (int j = 0; j < i; j++)
182                 fdlist[result++] = ke_list[j].ident;
183 #endif
184 #ifdef USE_EPOLL
185         int i = epoll_wait(EngineHandle, events, 65535, 100);
186         for (int j = 0; j < i; j++)
187                 fdlist[result++] = events[j].data.fd;
188 #endif
189         return result;
190 }
191
192 std::string SocketEngine::GetName()
193 {
194 #ifdef USE_SELECT
195         return "select";
196 #endif
197 #ifdef USE_KQUEUE
198         return "kqueue";
199 #endif
200 #ifdef USE_EPOLL
201         return "epoll";
202 #endif
203         return "misconfigured";
204 }