* See: http://www.inspircd.org/wiki/index.php/Credits
*
* This program is free but copyrighted software; see
- * the file COPYING for details.
+ * the file COPYING for details.
*
* ---------------------------------------------------
*/
#ifndef __SOCKETENGINE_IOCP__
#define __SOCKETENGINE_IOCP__
-#define READ_BUFFER_SIZE 500
+#define READ_BUFFER_SIZE 600
#define USING_IOCP 1
#include "inspircd_config.h"
#include "inspircd.h"
#include "socketengine.h"
+/** Socket overlapped event types
+ */
enum SocketIOEvent
{
+ /** Read ready */
SOCKET_IO_EVENT_READ_READY = 0,
+ /** Write ready */
SOCKET_IO_EVENT_WRITE_READY = 1,
+ /** Accept ready */
SOCKET_IO_EVENT_ACCEPT = 2,
+ /** Error occured */
SOCKET_IO_EVENT_ERROR = 3,
+ /** Number of events */
NUM_SOCKET_IO_EVENTS = 4,
};
+/** Represents a windows overlapped IO event
+ */
class Overlapped
{
public:
+ /** Overlap event */
OVERLAPPED m_overlap;
+ /** Type of event */
SocketIOEvent m_event;
- int m_params;
-
+#ifdef WIN64
+ /** Parameters */
+ unsigned __int64 m_params;
+#else
+ /** Parameters */
+ unsigned long m_params;
+#endif
+ /** Create an overlapped event
+ */
Overlapped(SocketIOEvent ev, int params) : m_event(ev), m_params(params)
{
memset(&m_overlap, 0, sizeof(OVERLAPPED));
}
};
+/** Specific to UDP sockets with overlapped IO
+ */
+struct udp_overlap
+{
+ unsigned char udp_buffer[600];
+ unsigned long udp_len;
+ sockaddr udp_sockaddr[2];
+ unsigned long udp_sockaddr_len;
+};
+
+/** Specific to accepting sockets with overlapped IO
+ */
struct accept_overlap
{
int socket;
char buf[1024];
};
+/** Implementation of SocketEngine that implements windows IO Completion Ports
+ */
class IOCPEngine : public SocketEngine
{
/** Creates a "fake" file descriptor for use with an IOCP socket.
* in a future release.
* @return -1 if there are no free slots, and an integer if it finds one.
*/
- __inline int GenerateFd()
+ __inline int GenerateFd(int RealFd)
{
- register int i = 0;
- for(; i < MAX_DESCRIPTORS; ++i)
- if(ref[i] == 0)
- return i;
+ int index_hash = RealFd % MAX_DESCRIPTORS;
+ if(ref[index_hash] == 0)
+ return index_hash;
+ else
+ {
+ register int i = 0;
+ for(; i < MAX_DESCRIPTORS; ++i)
+ if(ref[i] == 0)
+ return i;
+ }
return -1;
}
map<int, EventHandler*> m_binding;
public:
+ /** Holds the preallocated buffer passed to WSARecvFrom
+ * function. Yes, I know, it's a dirty hack.
+ */
+ udp_overlap * udp_ov;
+
/** Creates an IOCP Socket Engine
* @param Instance The creator of this object
*/
* @return A pointer to the event handler, or NULL
*/
EventHandler* GetIntRef(int fd);
-};
-//typedef void(*OpHandler)(EventHandler)
-/** Event Handler Array
- */
+ bool BoundsCheckFd(EventHandler* eh);
+
+ virtual int Accept(EventHandler* fd, sockaddr *addr, socklen_t *addrlen);
+
+ virtual int RecvFrom(EventHandler* fd, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen);
+
+ virtual int Blocking(int fd);
+
+ virtual int NonBlocking(int fd);
+
+ virtual int GetSockName(EventHandler* fd, sockaddr *name, socklen_t* name);
+
+ virtual int Close(int fd);
+
+ virtual int Close(EventHandler* fd);
+};
/** Creates a SocketEngine
*/