]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/socketengine.cpp
Made compile on freebsd
[user/henk/code/inspircd.git] / src / socketengine.cpp
1 #include "inspircd_config.h"
2 #include "globals.h"
3 #include "inspircd.h"
4 #ifdef USE_EPOLL
5 #include <sys/epoll.h>
6 #define EP_DELAY 5
7 #endif
8 #ifdef USE_KQUEUE
9 #include <sys/types.h>
10 #include <sys/event.h>
11 #include <sys/time.h>
12 #endif
13 #include <vector>
14 #include <string>
15 #include "socketengine.h"
16
17 char ref[65535];
18
19 const char X_LISTEN             = 0;
20 const char X_ESTAB_CLIENT       = 1;
21 const char X_ESTAB_MODULE       = 2;
22 const char X_ESTAB_DNS          = 3;
23
24 const char X_READBIT            = 0x80;
25
26 SocketEngine::SocketEngine()
27 {
28 #ifdef USE_EPOLL
29         EngineHandle = epoll_create(65535);
30 #endif
31 #ifdef USE_KQUEUE
32         EngineHandle = kqueue();
33 #endif
34 }
35
36 SocketEngine::~SocketEngine()
37 {
38 #ifdef USE_EPOLL
39         close(EngineHandle);
40 #endif
41 #ifdef USE_KQUEUE
42         close(EngineHandle);
43 #endif
44 }
45
46 bool SocketEngine::AddFd(int fd, bool readable, char type)
47 {
48         this->fds.push_back(fd);
49         if (readable)
50                 ref[fd] |= X_READBIT;
51 #ifdef USE_EPOLL
52         struct epoll_event ev;
53         log(DEBUG,"epoll: Adduser to events, ep=%d socket=%d",EngineHandle,fd);
54         readable ? ev.events = EPOLLIN | EPOLLET : ev.events = EPOLLOUT | EPOLLET;
55         ev.data.fd = fd;
56         int i = epoll_ctl(EngineHandle, EPOLL_CTL_ADD, fd, &ev);
57         if (i < 0)
58         {
59                 log(DEBUG,"epoll: List insertion failure!");
60                 return false;
61         }
62 #endif
63 #ifdef USE_KQUEUE
64         struct kevent ke;
65         log(DEBUG,"kqueue: Add user to events, kq=%d socket=%d",EngineHandle,fd);
66         EV_SET(&ke, fd, readable ? EVFILT_READ : EVFILT_WRITE, EV_ADD, 0, 0, NULL);
67         int i = kevent(EngineHandle, &ke, 1, 0, 0, NULL);
68         if (i == -1)
69         {
70                 log(DEBUG,"kqueue: List insertion failure!");
71                 return false;
72         }
73 #endif
74 return true;
75 }
76
77 bool SocketEngine::DelFd(int fd)
78 {
79         bool found = false;
80         for (std::vector<int>::iterator i = fds.begin(); i != fds.end(); i++)
81         {
82                 if (*i == fd)
83                 {
84                         fds.erase(i);
85                         found = true;
86                 }
87         }
88 #ifdef USE_KQUEUE
89         struct kevent ke;
90         EV_SET(&ke, fd, ref[fd] && X_READBIT ? EVFILT_READ : EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
91         int i = kevent(EngineHandle, &ke, 1, 0, 0, NULL);
92         if (i == -1)
93         {
94                 log(DEBUG,"kqueue: Failed to remove user from queue!");
95                 return false;
96         }
97 #endif
98 #ifdef USE_EPOLL
99         struct epoll_event ev;
100         ref[fd] && X_READBIT ? ev.events = EPOLLIN | EPOLLET : ev.events = EPOLLOUT | EPOLLET;
101         ev.data.fd = fd;
102         int i = epoll_ctl(EngineHandle, EPOLL_CTL_DEL, fd, &ev);
103         if (i < 0)
104         {
105                 log(DEBUG,"epoll: List deletion failure!");
106                 return false;
107         }
108 #endif
109         ref[fd] = 0;
110         return found;
111 }
112
113 bool SocketEngine::Wait(std::vector<int> &fdlist)
114 {
115         fdlist.clear();
116 #ifdef USE_SELECT
117         int highest_fd = 0;
118         timeval tval;
119         int sresult;
120         for (unsigned int a = 0; a < fds.size(); a++)
121         {
122                 if (ref[fds[a]] && X_READBIT)
123                 {
124                         FD_SET (fds[a], &rfdset);
125                 }
126                 else
127                 {
128                         FD_SET (fds[a], &wfdset);
129                 }
130                 
131         }
132         tval.tv_sec = 0;
133         tval.tv_usec = 1000L;
134         sresult = select(FD_SETSIZE, &rfdset, &wfdset, NULL, &tval);
135         if (sresult > 0)
136         {
137                 for (unsigned int a = 0; a < fds.size(); a++)
138                 {
139                         if ((FD_ISSET (fds[a], &rfdset)) || (FD_ISSET (fds[a], &wfdset)))
140                                 fdlist.push_back(fds[a]);
141                 }
142         }
143 #endif
144 #ifdef USE_KQUEUE
145         ts.tv_nsec = 1000L;
146         ts.tv_sec = 0;
147         int i = kevent(EngineHandle, NULL, 0, &ke_list[0], 65535, &ts);
148         for (int j = 0; j < i; j++)
149                 fdlist.push_back(ke_list[j].ident);
150 #endif
151 #ifdef USE_EPOLL
152         int i = epoll_wait(EngineHandle, events, 65535, 1);
153         for (int j = 0; j < i; j++)
154                 fdlist.push_back(event[0].data.fd);
155 #endif
156         return true;
157 }
158
159 std::string SocketEngine::GetName()
160 {
161 #ifdef USE_SELECT
162         return "select";
163 #endif
164 #ifdef USE_KQUEUE
165         return "kqueue";
166 #endif
167 #ifdef USE_EPOLL
168         return "epoll";
169 #endif
170         return "misconfigured";
171 }