#include <socketengine.h>
Collaboration diagram for SocketEngine:
Public Member Functions | |
SocketEngine () | |
Constructor The constructor transparently initializes the socket engine which the ircd is using. | |
~SocketEngine () | |
Destructor The destructor transparently tidies up any resources used by the socket engine. | |
bool | AddFd (int fd, bool readable, char type) |
Add a file descriptor to the engine Use AddFd to add a file descriptor to the engine and have the socket engine monitor it. | |
char | GetType (int fd) |
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. | |
bool | DelFd (int fd) |
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. | |
bool | Wait (std::vector< int > &fdlist) |
Waits for an event. | |
std::string | GetName () |
Returns the socket engines name This returns the name of the engine for use in /VERSION responses. | |
Private Attributes | |
std::vector< int > | fds |
int | EngineHandle |
kevent | ke_list [65535] |
timespec | ts |
The current version supports select, epoll and kqueue.
Definition at line 66 of file socketengine.h.
|
Constructor The constructor transparently initializes the socket engine which the ircd is using. 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. Definition at line 35 of file socketengine.cpp. References DEBUG, and EngineHandle. 00036 { 00037 log(DEBUG,"SocketEngine::SocketEngine()"); 00038 #ifdef USE_EPOLL 00039 EngineHandle = epoll_create(65535); 00040 #endif 00041 #ifdef USE_KQUEUE 00042 EngineHandle = kqueue(); 00043 #endif 00044 }
|
|
Destructor The destructor transparently tidies up any resources used by the socket engine.
Definition at line 46 of file socketengine.cpp. References DEBUG, and EngineHandle. 00047 { 00048 log(DEBUG,"SocketEngine::~SocketEngine()"); 00049 #ifdef USE_EPOLL 00050 close(EngineHandle); 00051 #endif 00052 #ifdef USE_KQUEUE 00053 close(EngineHandle); 00054 #endif 00055 }
|
|
Add a file descriptor to the engine Use AddFd to add a file descriptor to the engine and have the socket engine monitor it. You must provide a type (see the consts in socketengine.h) 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). Definition at line 65 of file socketengine.cpp. References DEBUG, EngineHandle, fds, ref, and X_READBIT. Referenced by InspSocket::InspSocket(), and InspSocket::Poll(). 00066 { 00067 if ((fd < 0) || (fd > 65535)) 00068 return false; 00069 this->fds.push_back(fd); 00070 ref[fd] = type; 00071 if (readable) 00072 { 00073 log(DEBUG,"Set readbit"); 00074 ref[fd] |= X_READBIT; 00075 } 00076 log(DEBUG,"Add socket %d",fd); 00077 #ifdef USE_EPOLL 00078 struct epoll_event ev; 00079 log(DEBUG,"epoll: Add socket to events, ep=%d socket=%d",EngineHandle,fd); 00080 readable ? ev.events = EPOLLIN | EPOLLET : ev.events = EPOLLOUT | EPOLLET; 00081 ev.data.fd = fd; 00082 int i = epoll_ctl(EngineHandle, EPOLL_CTL_ADD, fd, &ev); 00083 if (i < 0) 00084 { 00085 log(DEBUG,"epoll: List insertion failure!"); 00086 return false; 00087 } 00088 #endif 00089 #ifdef USE_KQUEUE 00090 struct kevent ke; 00091 log(DEBUG,"kqueue: Add socket to events, kq=%d socket=%d",EngineHandle,fd); 00092 EV_SET(&ke, fd, readable ? EVFILT_READ : EVFILT_WRITE, EV_ADD, 0, 0, NULL); 00093 int i = kevent(EngineHandle, &ke, 1, 0, 0, NULL); 00094 if (i == -1) 00095 { 00096 log(DEBUG,"kqueue: List insertion failure!"); 00097 return false; 00098 } 00099 #endif 00100 return true; 00101 }
|
|
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.
Definition at line 103 of file socketengine.cpp. References DEBUG, EngineHandle, fds, ref, and X_READBIT. Referenced by InspSocket::Poll(), and Server::UserToPseudo(). 00104 { 00105 log(DEBUG,"SocketEngine::DelFd(%d)",fd); 00106 00107 if ((fd < 0) || (fd > 65535)) 00108 return false; 00109 00110 bool found = false; 00111 for (std::vector<int>::iterator i = fds.begin(); i != fds.end(); i++) 00112 { 00113 if (*i == fd) 00114 { 00115 fds.erase(i); 00116 log(DEBUG,"Deleted fd %d",fd); 00117 found = true; 00118 break; 00119 } 00120 } 00121 #ifdef USE_KQUEUE 00122 struct kevent ke; 00123 EV_SET(&ke, fd, ref[fd] && X_READBIT ? EVFILT_READ : EVFILT_WRITE, EV_DELETE, 0, 0, NULL); 00124 int i = kevent(EngineHandle, &ke, 1, 0, 0, NULL); 00125 if (i == -1) 00126 { 00127 log(DEBUG,"kqueue: Failed to remove socket from queue!"); 00128 return false; 00129 } 00130 #endif 00131 #ifdef USE_EPOLL 00132 struct epoll_event ev; 00133 ref[fd] && X_READBIT ? ev.events = EPOLLIN | EPOLLET : ev.events = EPOLLOUT | EPOLLET; 00134 ev.data.fd = fd; 00135 int i = epoll_ctl(EngineHandle, EPOLL_CTL_DEL, fd, &ev); 00136 if (i < 0) 00137 { 00138 log(DEBUG,"epoll: List deletion failure!"); 00139 return false; 00140 } 00141 #endif 00142 ref[fd] = 0; 00143 return found; 00144 }
|
|
Returns the socket engines name This returns the name of the engine for use in /VERSION responses.
Definition at line 196 of file socketengine.cpp. 00197 { 00198 #ifdef USE_SELECT 00199 return "select"; 00200 #endif 00201 #ifdef USE_KQUEUE 00202 return "kqueue"; 00203 #endif 00204 #ifdef USE_EPOLL 00205 return "epoll"; 00206 #endif 00207 return "misconfigured"; 00208 }
|
|
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. 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. Definition at line 57 of file socketengine.cpp. References ref, and X_EMPTY_SLOT. 00058 { 00059 if ((fd < 0) || (fd > 65535)) 00060 return X_EMPTY_SLOT; 00061 /* Mask off the top bit used for 'read/write' state */ 00062 return (ref[fd] & ~0x80); 00063 }
|
|
Waits for an event. 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. Definition at line 146 of file socketengine.cpp. References DEBUG, EngineHandle, fds, ke_list, ref, ts, and X_READBIT. 00147 { 00148 fdlist.clear(); 00149 #ifdef USE_SELECT 00150 FD_ZERO(&wfdset); 00151 FD_ZERO(&rfdset); 00152 timeval tval; 00153 int sresult; 00154 for (unsigned int a = 0; a < fds.size(); a++) 00155 { 00156 if (ref[fds[a]] & X_READBIT) 00157 { 00158 FD_SET (fds[a], &rfdset); 00159 } 00160 else 00161 { 00162 FD_SET (fds[a], &wfdset); 00163 } 00164 00165 } 00166 tval.tv_sec = 0; 00167 tval.tv_usec = 1000L; 00168 sresult = select(FD_SETSIZE, &rfdset, &wfdset, NULL, &tval); 00169 if (sresult > 0) 00170 { 00171 for (unsigned int a = 0; a < fds.size(); a++) 00172 { 00173 if ((FD_ISSET (fds[a], &rfdset)) || (FD_ISSET (fds[a], &wfdset))) 00174 { 00175 log(DEBUG,"...Adding active %d",fds[a]); 00176 fdlist.push_back(fds[a]); 00177 } 00178 } 00179 } 00180 #endif 00181 #ifdef USE_KQUEUE 00182 ts.tv_nsec = 1000L; 00183 ts.tv_sec = 0; 00184 int i = kevent(EngineHandle, NULL, 0, &ke_list[0], 65535, &ts); 00185 for (int j = 0; j < i; j++) 00186 fdlist.push_back(ke_list[j].ident); 00187 #endif 00188 #ifdef USE_EPOLL 00189 int i = epoll_wait(EngineHandle, events, 65535, 1); 00190 for (int j = 0; j < i; j++) 00191 fdlist.push_back(events[j].data.fd); 00192 #endif 00193 return true; 00194 }
|
|
Definition at line 69 of file socketengine.h. Referenced by AddFd(), DelFd(), SocketEngine(), Wait(), and ~SocketEngine(). |
|
Definition at line 68 of file socketengine.h. |
|
Definition at line 74 of file socketengine.h. Referenced by Wait(). |
|
Definition at line 75 of file socketengine.h. Referenced by Wait(). |