1 /* +------------------------------------+
2 * | Inspire Internet Relay Chat Daemon |
3 * +------------------------------------+
5 * InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev.
7 * <brain@chatspike.net>
8 * <Craig@chatspike.net>
10 * Written by Craig Edwards, Craig McLure, and others.
11 * This program is free but copyrighted software; see
12 * the file COPYING for details.
14 * ---------------------------------------------------
17 #ifndef __SOCKETENGINE__
18 #define __SOCKETENGINE__
23 #include "inspircd_config.h"
26 /** Types of event an EventHandler may receive.
27 * EVENT_READ is a readable file descriptor,
28 * and EVENT_WRITE is a writeable file descriptor.
38 /** This class is a basic I/O handler class.
39 * Any object which wishes to receive basic I/O events
40 * from the socketengine must derive from this class and
41 * implement the HandleEvent() method. The derived class
42 * must then be added to SocketEngine using the method
43 * SocketEngine::AddFd(), after which point the derived
44 * class will receive events to its HandleEvent() method.
45 * The derived class should also implement one of Readable()
46 * and Writeable(). In the current implementation, only
47 * Readable() is used. If this returns true, the socketengine
48 * inserts a readable socket. If it is false, the socketengine
49 * inserts a writeable socket. The derived class should never
50 * change the value this function returns without first
51 * deleting the socket from the socket engine. The only
52 * requirement beyond this for an event handler is that it
53 * must have a file descriptor. What this file descriptor
54 * is actually attached to is completely up to you.
56 class EventHandler : public Extensible
60 * All events which can be handled
61 * must have a file descriptor.
62 * This allows you to add events for
63 * sockets, fifo's, pipes, and various
68 /** Get the current file descriptor
69 * @return The file descriptor of this handler
73 /** Set a new file desciptor
74 * @param FD The new file descriptor. Do not
75 * call this method without first deleting the
76 * object from the SocketEngine if you have
77 * added it to a SocketEngine instance.
87 virtual ~EventHandler() {}
89 /** Override this function to indicate readability.
90 * @return This should return true if the function
91 * wishes to receive EVENT_READ events. Do not change
92 * what this function returns while the event handler
93 * is still added to a SocketEngine instance!
94 * If this function is unimplemented, the base class
97 virtual bool Readable();
99 /** Override this function to indicate writeability.
100 * @return This should return true if the function
101 * wishes to receive EVENT_WRITE events. Do not change
102 * what this function returns while the event handler
103 * is still added to a SocketEngine instance!
104 * If this function is unimplemented, the base class
107 virtual bool Writeable();
109 /** Process an I/O event.
110 * You MUST implement this function in your derived
111 * class, and it will be called whenever read or write
112 * events are received, depending on what your functions
113 * Readable() and Writeable() returns.
114 * @param et either one of EVENT_READ for read events,
115 * and EVENT_WRITE for write events.
117 virtual void HandleEvent(EventType et) = 0;
120 /** Provides basic file-descriptor-based I/O support.
121 * The actual socketengine class presents the
122 * same interface on all operating systems, but
123 * its private members and internal behaviour
124 * should be treated as blackboxed, and vary
125 * from system to system and upon the config
126 * settings chosen by the server admin. The current
127 * version supports select, epoll and kqueue.
128 * The configure script will enable a socket engine
129 * based upon what OS is detected, and will derive
130 * a class from SocketEngine based upon what it finds.
131 * The derived classes file will also implement a
132 * classfactory, SocketEngineFactory, which will
133 * create a derived instance of SocketEngine using
134 * polymorphism so that the core and modules do not
135 * have to be aware of which SocketEngine derived
136 * class they are using.
138 class SocketEngine : public Extensible
143 InspIRCd* ServerInstance;
144 /** Handle to socket engine, where needed.
147 /** Current number of descriptors in the engine
150 /** Reference table, contains all current handlers
152 EventHandler* ref[MAX_DESCRIPTORS];
156 * The constructor transparently initializes
157 * the socket engine which the ircd is using.
158 * Please note that if there is a catastrophic
159 * failure (for example, you try and enable
160 * epoll on a 2.4 linux kernel) then this
161 * function may bail back to the shell.
162 * @param Instance The creator/owner of this object
164 SocketEngine(InspIRCd* Instance);
167 * The destructor transparently tidies up
168 * any resources used by the socket engine.
170 virtual ~SocketEngine();
172 /** Add an EventHandler object to the engine.
173 * Use AddFd to add a file descriptor to the
174 * engine and have the socket engine monitor
175 * it. You must provide an object derived from
176 * EventHandler which implements HandleEvent()
177 * and optionally Readable() and Writeable().
178 * @param eh An event handling object to add
180 virtual bool AddFd(EventHandler* eh);
182 /** Returns the maximum number of file descriptors
183 * you may store in the socket engine at any one time.
184 * @return The maximum fd value
186 virtual int GetMaxFds();
188 /** Returns the number of file descriptor slots
189 * which are available for storing fds.
190 * @return The number of remaining fd's
192 virtual int GetRemainingFds();
194 /** Delete an event handler from the engine.
195 * This function call deletes an EventHandler
196 * from the engine, returning true if it succeeded
197 * and false if it failed. This does not free the
198 * EventHandler pointer using delete, if this is
199 * required you must do this yourself.
200 * @param eh The event handler object to remove
201 * @return True if the event handler was removed
203 virtual bool DelFd(EventHandler* eh);
205 /** Returns true if a file descriptor exists in
206 * the socket engine's list.
207 * @param fd The event handler to look for
208 * @return True if this fd has an event handler
212 /** Returns the EventHandler attached to a specific fd.
213 * If the fd isnt in the socketengine, returns NULL.
214 * @param fd The event handler to look for
215 * @return A pointer to the event handler, or NULL
217 EventHandler* GetRef(int fd);
219 /** Waits for events and dispatches them to handlers.
220 * Please note that this doesnt wait long, only
221 * a couple of milliseconds. It returns the number of
222 * events which occured during this call.
223 * This method will dispatch events to their handlers
224 * by calling their EventHandler::HandleEvent()
225 * methods with the neccessary EventType value.
226 * @return The number of events which have occured.
228 virtual int DispatchEvents();
230 /** Returns the socket engines name.
231 * This returns the name of the engine for use
232 * in /VERSION responses.
233 * @return The socket engine name
235 virtual std::string GetName();