1 /* +------------------------------------+
2 * | Inspire Internet Relay Chat Daemon |
3 * +------------------------------------+
5 * InspIRCd: (C) 2002-2007 InspIRCd Development Team
6 * See: http://www.inspircd.org/wiki/index.php/Credits
8 * This program is free but copyrighted software; see
9 * the file COPYING for details.
11 * ---------------------------------------------------
14 #ifndef __SOCKETENGINE_IOCP__
15 #define __SOCKETENGINE_IOCP__
17 #define READ_BUFFER_SIZE 600
20 #include "inspircd_config.h"
21 #include "inspircd_win32wrapper.h"
24 #include "socketengine.h"
26 /** Socket overlapped event types
31 SOCKET_IO_EVENT_READ_READY = 0,
33 SOCKET_IO_EVENT_WRITE_READY = 1,
35 SOCKET_IO_EVENT_ACCEPT = 2,
37 SOCKET_IO_EVENT_ERROR = 3,
38 /** Number of events */
39 NUM_SOCKET_IO_EVENTS = 4,
42 /** Represents a windows overlapped IO event
50 SocketIOEvent m_event;
53 unsigned __int64 m_params;
56 unsigned long m_params;
58 /** Create an overlapped event
60 Overlapped(SocketIOEvent ev, int params) : m_event(ev), m_params(params)
62 memset(&m_overlap, 0, sizeof(OVERLAPPED));
66 /** Specific to UDP sockets with overlapped IO
70 unsigned char udp_buffer[600];
71 unsigned long udp_len;
72 sockaddr udp_sockaddr[2];
73 unsigned long udp_sockaddr_len;
76 /** Specific to accepting sockets with overlapped IO
84 /** Implementation of SocketEngine that implements windows IO Completion Ports
86 class IOCPEngine : public SocketEngine
88 /** Creates a "fake" file descriptor for use with an IOCP socket.
89 * This is a little slow, but it isnt called too much. We'll fix it
90 * in a future release.
91 * @return -1 if there are no free slots, and an integer if it finds one.
93 __inline int GenerateFd(int RealFd)
95 int index_hash = RealFd % MAX_DESCRIPTORS;
96 if(ref[index_hash] == 0)
101 for(; i < MAX_DESCRIPTORS; ++i)
108 /** Global I/O completion port that sockets attach to.
110 HANDLE m_completionPort;
112 /** This is kinda shitty... :/ for getting an address from a real fd.
114 map<int, EventHandler*> m_binding;
117 /** Holds the preallocated buffer passed to WSARecvFrom
118 * function. Yes, I know, it's a dirty hack.
120 udp_overlap * udp_ov;
122 /** Creates an IOCP Socket Engine
123 * @param Instance The creator of this object
125 IOCPEngine(InspIRCd* Instance);
127 /** Deletes an IOCP socket engine and all the attached sockets
131 /** Adds an event handler to the completion port, and sets up initial events.
132 * @param eh EventHandler to add
133 * @return True if success, false if no room
135 bool AddFd(EventHandler* eh);
137 /** Gets the maximum number of file descriptors that this engine can handle.
138 * @return The number of file descriptors
140 __inline int GetMaxFds() { return MAX_DESCRIPTORS; }
142 /** Gets the number of free/remaining file descriptors under this engine.
143 * @return Remaining count
145 __inline int GetRemainingFds()
147 register int count = 0;
149 for(; i < MAX_DESCRIPTORS; ++i)
155 /** Removes a file descriptor from the set, preventing it from receiving any more events
156 * @return True if remove was successful, false otherwise
158 bool DelFd(EventHandler* eh, bool force = false);
160 /** Called every loop to handle input/output events for all sockets under this engine
161 * @return The number of "changed" sockets.
163 int DispatchEvents();
165 /** Gets the name of this socket engine as a string.
166 * @return string of socket engine name
168 std::string GetName();
170 /** Queues a Write event on the specified event handler.
171 * @param eh EventHandler that needs data sent on
173 void WantWrite(EventHandler* eh);
175 /** Posts a completion event on the specified socket.
176 * @param eh EventHandler for message
177 * @param type Event Type
178 * @param param Event Parameter
179 * @return True if added, false if not
181 bool PostCompletionEvent(EventHandler* eh, SocketIOEvent type, int param);
183 /** Posts a read event on the specified socket
184 * @param eh EventHandler (socket)
186 void PostReadEvent(EventHandler* eh);
188 /** Posts an accept event on the specified socket
189 * @param eh EventHandler (socket)
191 void PostAcceptEvent(EventHandler* eh);
193 /** Returns the EventHandler attached to a specific fd.
194 * If the fd isnt in the socketengine, returns NULL.
195 * @param fd The event handler to look for
196 * @return A pointer to the event handler, or NULL
198 EventHandler* GetRef(int fd);
200 /** Returns true if a file descriptor exists in
201 * the socket engine's list.
202 * @param fd The event handler to look for
203 * @return True if this fd has an event handler
207 /** Returns the EventHandler attached to a specific fd.
208 * If the fd isnt in the socketengine, returns NULL.
209 * @param fd The event handler to look for
210 * @return A pointer to the event handler, or NULL
212 EventHandler* GetIntRef(int fd);
214 bool BoundsCheckFd(EventHandler* eh);
217 /** Creates a SocketEngine
219 class SocketEngineFactory
222 /** Create a new instance of SocketEngine based on IOCPEngine
224 SocketEngine* Create(InspIRCd* Instance) { return new IOCPEngine(Instance); }