Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

SocketEngine Class Reference

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. More...

#include <socketengine.h>

Collaboration diagram for SocketEngine:

Collaboration graph
[legend]
List of all members.

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

Detailed Description

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.

Definition at line 66 of file socketengine.h.


Constructor & Destructor Documentation

SocketEngine::SocketEngine  ) 
 

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, EngineHandle, and log().

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 }

SocketEngine::~SocketEngine  ) 
 

Destructor The destructor transparently tidies up any resources used by the socket engine.

Definition at line 46 of file socketengine.cpp.

References DEBUG, EngineHandle, and log().

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 }


Member Function Documentation

bool SocketEngine::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.

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, log(), ref, and X_READBIT.

Referenced by AddClient(), 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 }

bool SocketEngine::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.

Definition at line 103 of file socketengine.cpp.

References DEBUG, EngineHandle, fds, log(), ref, and X_READBIT.

Referenced by kill_link(), kill_link_silent(), 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 }

std::string SocketEngine::GetName  ) 
 

Returns the socket engines name This returns the name of the engine for use in /VERSION responses.

Definition at line 193 of file socketengine.cpp.

00194 {
00195 #ifdef USE_SELECT
00196         return "select";
00197 #endif
00198 #ifdef USE_KQUEUE
00199         return "kqueue";
00200 #endif
00201 #ifdef USE_EPOLL
00202         return "epoll";
00203 #endif
00204         return "misconfigured";
00205 }

char SocketEngine::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.

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 }

bool SocketEngine::Wait std::vector< int > &  fdlist  ) 
 

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 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 = 100L;
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                                 fdlist.push_back(fds[a]);
00175                 }
00176         }
00177 #endif
00178 #ifdef USE_KQUEUE
00179         ts.tv_nsec = 10000L;
00180         ts.tv_sec = 0;
00181         int i = kevent(EngineHandle, NULL, 0, &ke_list[0], 65535, &ts);
00182         for (int j = 0; j < i; j++)
00183                 fdlist.push_back(ke_list[j].ident);
00184 #endif
00185 #ifdef USE_EPOLL
00186         int i = epoll_wait(EngineHandle, events, 65535, 100);
00187         for (int j = 0; j < i; j++)
00188                 fdlist.push_back(events[j].data.fd);
00189 #endif
00190         return true;
00191 }


Member Data Documentation

int SocketEngine::EngineHandle [private]
 

Definition at line 69 of file socketengine.h.

Referenced by AddFd(), DelFd(), SocketEngine(), Wait(), and ~SocketEngine().

std::vector<int> SocketEngine::fds [private]
 

Definition at line 68 of file socketengine.h.

Referenced by AddFd(), DelFd(), and Wait().

struct kevent SocketEngine::ke_list[65535] [private]
 

Definition at line 74 of file socketengine.h.

Referenced by Wait().

struct timespec SocketEngine::ts [private]
 

Definition at line 75 of file socketengine.h.

Referenced by Wait().


The documentation for this class was generated from the following files:
Generated on Mon Dec 19 18:05:23 2005 for InspIRCd by  doxygen 1.4.4-20050815