*/
#include "socketengine_iocp.h"
+#include "exitcodes.h"
#include <mswsock.h>
IOCPEngine::IOCPEngine(InspIRCd * Instance) : SocketEngine(Instance)
/* Create completion port */
m_completionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, (ULONG_PTR)0, 0);
+ if (!m_completionPort)
+ {
+ ServerInstance->Log(SPARSE,"ERROR: Could not initialize socket engine. Your kernel probably does not have the proper features.");
+ ServerInstance->Log(SPARSE,"ERROR: this is a fatal error, exiting now.");
+ printf("ERROR: Could not initialize socket engine. Your kernel probably does not have the proper features.");
+ printf("ERROR: this is a fatal error, exiting now.");
+ InspIRCd::Exit(EXIT_STATUS_SOCKETENGINE);
+ }
+
/* Null variables out. */
CurrentSetSize = 0;
EngineHandle = 0;
bool IOCPEngine::AddFd(EventHandler* eh)
{
+ /* Does it at least look valid? */
+ if (!eh)
+ return false;
+
int fake_fd = GenerateFd(eh->GetFd());
int is_accept = 0;
int opt_len = sizeof(int);
- if(fake_fd < 0)
+
+ /* In range? */
+ if ((fake_fd < 0) || (fake_fd > MAX_DESCRIPTORS))
+ return false;
+
+ /* Already an entry here */
+ if (ref[fake_fd])
return false;
/* are we a listen socket? */
unsigned long completion_key = (ULONG_PTR)eh->m_internalFd;
/* assign the socket to the completion port */
- if(!CreateIoCompletionPort((HANDLE)eh->GetFd(), m_completionPort, completion_key, 0))
+ if (!CreateIoCompletionPort((HANDLE)eh->GetFd(), m_completionPort, completion_key, 0))
return false;
/* set up binding, increase set size */
bool IOCPEngine::DelFd(EventHandler* eh, bool force /* = false */)
{
+ if (!eh)
+ return false;
+
int fake_fd = eh->m_internalFd;
int fd = eh->GetFd();
- if(ref[fake_fd] == 0)
+ if (!ref[fake_fd])
return false;
ServerInstance->Log(DEBUG, "Removing fake fd %u, real fd %u, address 0x%p", fake_fd, eh->GetFd(), eh);
return false;
/* Free the buffer, and delete the event. */
- if(eh->m_readEvent != 0)
+ if (eh->m_readEvent != 0)
{
if(((Overlapped*)eh->m_readEvent)->m_params != 0)
delete ((udp_overlap*)((Overlapped*)eh->m_readEvent)->m_params);
void IOCPEngine::WantWrite(EventHandler* eh)
{
+ if (!eh)
+ return;
+
/* Post event - write begin */
if(!eh->m_writeEvent)
{
bool IOCPEngine::PostCompletionEvent(EventHandler * eh, SocketIOEvent type, int param)
{
+ if (!eh)
+ return false;
+
Overlapped * ov = new Overlapped(type, param);
ULONG_PTR completion_key = (ULONG_PTR)eh->m_internalFd;
return PostQueuedCompletionStatus(m_completionPort, 0, completion_key, &ov->m_overlap);
void IOCPEngine::PostReadEvent(EventHandler * eh)
{
+ if (!eh)
+ return;
+
Overlapped * ov = new Overlapped(SOCKET_IO_EVENT_READ_READY, 0);
DWORD flags = 0;
DWORD r_length = 0;
int ret;
unsigned long bytes_recv;
- while(GetQueuedCompletionStatus(m_completionPort, &len, &intfd, &overlap, 1000))
+ while (GetQueuedCompletionStatus(m_completionPort, &len, &intfd, &overlap, 1000))
{
// woot, we got an event on a socket :P
eh = ref[intfd];
ov = CONTAINING_RECORD(overlap, Overlapped, m_overlap);
- if(eh == 0) continue;
+
+ if (eh == 0)
+ continue;
+
switch(ov->m_event)
{
case SOCKET_IO_EVENT_WRITE_READY:
void IOCPEngine::PostAcceptEvent(EventHandler * eh)
{
+ if (!eh)
+ return;
+
int fd = WSASocket(AF_INET, SOCK_STREAM, 0, 0, 0, WSA_FLAG_OVERLAPPED);
int len = sizeof(sockaddr_in) + 16;
DWORD dwBytes;