git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11828
e03df62e-2008-0410-955e-
edbf42e46eb7
*/
std::map<int, EventHandler*> m_binding;
*/
std::map<int, EventHandler*> m_binding;
+ LocalIntExt fdExt;
+ LocalIntExt readExt;
+ LocalIntExt writeExt;
+ LocalIntExt acceptExt;
+
public:
/** Holds the preallocated buffer passed to WSARecvFrom
* function. Yes, I know, it's a dirty hack.
public:
/** Holds the preallocated buffer passed to WSARecvFrom
* function. Yes, I know, it's a dirty hack.
#include <mswsock.h>
IOCPEngine::IOCPEngine()
#include <mswsock.h>
IOCPEngine::IOCPEngine()
+: fdExt("internal_fd", NULL),
+ readExt("windows_readevent", NULL),
+ writeExt("windows_writeevent", NULL),
+ acceptExt("windows_acceptevent", NULL)
{
MAX_DESCRIPTORS = 10240;
{
MAX_DESCRIPTORS = 10240;
getsockopt(eh->GetFd(), SOL_SOCKET, SO_ACCEPTCONN, (char*)&is_accept, &opt_len);
/* set up the read event so the socket can actually receive data :P */
getsockopt(eh->GetFd(), SOL_SOCKET, SO_ACCEPTCONN, (char*)&is_accept, &opt_len);
/* set up the read event so the socket can actually receive data :P */
- eh->Extend("internal_fd", fake_fd);
+ fdExt.set(eh, *fake_fd);
unsigned long completion_key = (ULONG_PTR)*fake_fd;
/* assign the socket to the completion port */
unsigned long completion_key = (ULONG_PTR)*fake_fd;
/* assign the socket to the completion port */
/* post a write event if there is data to be written */
if (event_mask & (FD_WANT_POLL_WRITE | FD_WANT_FAST_WRITE | FD_WANT_SINGLE_WRITE))
/* post a write event if there is data to be written */
if (event_mask & (FD_WANT_POLL_WRITE | FD_WANT_FAST_WRITE | FD_WANT_SINGLE_WRITE))
+ OnSetEvent(eh, event_mask, event_mask);
/* we're all good =) */
try
/* we're all good =) */
try
+ int* fake_fd = (int*)fdExt.get(eh);
- if (!eh->GetExt("internal_fd", fake_fd))
return false;
int fd = eh->GetFd();
return false;
int fd = eh->GetFd();
- void* m_readEvent = NULL;
- void* m_writeEvent = NULL;
- void* m_acceptEvent = NULL;
+ void* m_readEvent = (void*)readExt.get(eh);
+ void* m_writeEvent = (void*)writeExt.get(eh);
+ void* m_acceptEvent = (void*)acceptExt.get(eh);
ServerInstance->Logs->Log("SOCKET",DEBUG, "Removing fake fd %u, real fd %u, address 0x%p", *fake_fd, eh->GetFd(), eh);
ServerInstance->Logs->Log("SOCKET",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. */
return false;
/* Free the buffer, and delete the event. */
- if (eh->GetExt("windows_readevent", m_readEvent))
{
if(((Overlapped*)m_readEvent)->m_params != 0)
delete ((udp_overlap*)((Overlapped*)m_readEvent)->m_params);
delete ((Overlapped*)m_readEvent);
{
if(((Overlapped*)m_readEvent)->m_params != 0)
delete ((udp_overlap*)((Overlapped*)m_readEvent)->m_params);
delete ((Overlapped*)m_readEvent);
- eh->Shrink("windows_readevent");
- if(eh->GetExt("windows_writeevent", m_writeEvent))
{
delete ((Overlapped*)m_writeEvent);
{
delete ((Overlapped*)m_writeEvent);
- eh->Shrink("windows_writeevent");
- if(eh->GetExt("windows_acceptevent", m_acceptEvent))
{
delete ((accept_overlap*)((Overlapped*)m_acceptEvent)->m_params);
delete ((Overlapped*)m_acceptEvent);
{
delete ((accept_overlap*)((Overlapped*)m_acceptEvent)->m_params);
delete ((Overlapped*)m_acceptEvent);
- eh->Shrink("windows_accepevent");
m_binding.erase(eh->GetFd());
delete fake_fd;
m_binding.erase(eh->GetFd());
delete fake_fd;
- eh->Shrink("internal_fd");
/* decrement set size */
--CurrentSetSize;
/* decrement set size */
--CurrentSetSize;
- void* m_writeEvent = NULL;
+ void* m_writeEvent = (void*)writeExt.get(eh);
- int* fake_fd = NULL;
- if (!eh->GetExt("internal_fd", fake_fd))
+ int* fake_fd = (int*)fdExt.get(eh);
+ if (!fake_fd)
return;
/* Post event - write begin */
return;
/* Post event - write begin */
- if((new_mask & (FD_WANT_POLL_WRITE | FD_WANT_FAST_WRITE | FD_WANT_SINGLE_WRITE)) && !eh->GetExt("windows_writeevent", m_writeEvent))
+ if((new_mask & (FD_WANT_POLL_WRITE | FD_WANT_FAST_WRITE | FD_WANT_SINGLE_WRITE)) && !m_writeEvent)
{
ULONG_PTR completion_key = (ULONG_PTR)*fake_fd;
Overlapped * ov = new Overlapped(SOCKET_IO_EVENT_WRITE_READY, 0);
{
ULONG_PTR completion_key = (ULONG_PTR)*fake_fd;
Overlapped * ov = new Overlapped(SOCKET_IO_EVENT_WRITE_READY, 0);
- eh->Shrink("windows_writeevent");
- eh->Extend("windows_writeevent",ov);
+ writeExt.free(eh);
+ writeExt.set(eh, (intptr_t)ov);
PostQueuedCompletionStatus(m_completionPort, 0, completion_key, &ov->m_overlap);
}
}
PostQueuedCompletionStatus(m_completionPort, 0, completion_key, &ov->m_overlap);
}
}
- int* fake_fd = NULL;
- if (!eh->GetExt("internal_fd", fake_fd))
+ int* fake_fd = (int*)fdExt.get(eh);
+ if (!fake_fd)
return false;
Overlapped * ov = new Overlapped(type, param);
return false;
Overlapped * ov = new Overlapped(type, param);
- eh->Extend("windows_readevent", ov);
+ readExt.set(eh, (intptr_t)ov);
}
int IOCPEngine::DispatchEvents()
}
int IOCPEngine::DispatchEvents()
- void* m_readEvent = NULL;
- void* m_writeEvent = NULL;
-
- eh->GetExt("windows_readevent", m_readEvent);
- eh->GetExt("windows_writeevent", m_writeEvent);
-
TotalEvents++;
switch(ov->m_event)
TotalEvents++;
switch(ov->m_event)
case SOCKET_IO_EVENT_WRITE_READY:
{
WriteEvents++;
case SOCKET_IO_EVENT_WRITE_READY:
{
WriteEvents++;
- eh->Shrink("windows_writeevent");
SetEventMask(eh, eh->GetEventMask() & ~FD_WRITE_WILL_BLOCK);
eh->HandleEvent(EVENT_WRITE, 0);
}
SetEventMask(eh, eh->GetEventMask() & ~FD_WRITE_WILL_BLOCK);
eh->HandleEvent(EVENT_WRITE, 0);
}
udp_overlap * uv = (udp_overlap*)ov->m_params;
uv->udp_len = len;
this->udp_ov = uv;
udp_overlap * uv = (udp_overlap*)ov->m_params;
uv->udp_len = len;
this->udp_ov = uv;
- eh->Shrink("windows_readevent");
eh->HandleEvent(EVENT_READ, 0);
this->udp_ov = 0;
delete uv;
eh->HandleEvent(EVENT_READ, 0);
this->udp_ov = 0;
delete uv;
else
{
ret = ioctlsocket(eh->GetFd(), FIONREAD, &bytes_recv);
else
{
ret = ioctlsocket(eh->GetFd(), FIONREAD, &bytes_recv);
- eh->Shrink("windows_readevent");
if(ret != 0 || bytes_recv == 0)
{
/* end of file */
if(ret != 0 || bytes_recv == 0)
{
/* end of file */
ReadEvents++;
eh->HandleEvent(EVENT_READ, ov->m_params);
delete ((accept_overlap*)ov->m_params);
ReadEvents++;
eh->HandleEvent(EVENT_READ, ov->m_params);
delete ((accept_overlap*)ov->m_params);
- eh->Shrink("windows_acceptevent");
PostAcceptEvent(eh);
}
break;
PostAcceptEvent(eh);
}
break;
ao->socket = fd;
Overlapped* ov = new Overlapped(SOCKET_IO_EVENT_ACCEPT, (int)ao);
ao->socket = fd;
Overlapped* ov = new Overlapped(SOCKET_IO_EVENT_ACCEPT, (int)ao);
- eh->Extend("windows_acceptevent", ov);
+ acceptExt.set(eh, (intptr_t)ov);
if(AcceptEx(eh->GetFd(), fd, ao->buf, 0, len, len, &dwBytes, &ov->m_overlap) == FALSE)
{
if(AcceptEx(eh->GetFd(), fd, ao->buf, 0, len, len, &dwBytes, &ov->m_overlap) == FALSE)
{
bool IOCPEngine::BoundsCheckFd(EventHandler* eh)
{
bool IOCPEngine::BoundsCheckFd(EventHandler* eh)
{
+ int* internal_fd = (int*)fdExt.get(eh);
if (!eh || eh->GetFd() < 0)
return false;
if (!eh || eh->GetFd() < 0)
return false;
- if(!eh->GetExt("internal_fd", internal_fd))
return false;
if(*internal_fd > MAX_DESCRIPTORS)
return false;
if(*internal_fd > MAX_DESCRIPTORS)
{
//SOCKET s = fd->GetFd();
{
//SOCKET s = fd->GetFd();
- Overlapped* acceptevent = NULL;
- if (!fd->GetExt("windows_acceptevent", acceptevent))
+ Overlapped* acceptevent = (Overlapped*)acceptExt.get(fd);
+ if (!acceptevent)
/* Shit, no accept event on this socket! :( */
return -1;
/* Shit, no accept event on this socket! :( */
return -1;
int IOCPEngine::GetSockName(EventHandler* fd, sockaddr *name, socklen_t* namelen)
{
int IOCPEngine::GetSockName(EventHandler* fd, sockaddr *name, socklen_t* namelen)
{
- Overlapped* ovl = NULL;
+ Overlapped* ovl = (Overlapped*)acceptExt.get(fd);
- if (!fd->GetExt("windows_acceptevent", ovl))
return -1;
accept_overlap* ov = (accept_overlap*)ovl->m_params;
return -1;
accept_overlap* ov = (accept_overlap*)ovl->m_params;
int IOCPEngine::RecvFrom(EventHandler* fd, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
{
this->UpdateStats(len, 0);
int IOCPEngine::RecvFrom(EventHandler* fd, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
{
this->UpdateStats(len, 0);
- udp_overlap * ov = NULL;
- if (!fd->GetExt("windows_readevent", ov))
+ udp_overlap* ov = (udp_overlap*)readExt.get(fd);
+ if (!ov)
return -1;
memcpy(buf, ov->udp_buffer, ov->udp_len);
memcpy(from, ov->udp_sockaddr, *fromlen);
return -1;
memcpy(buf, ov->udp_buffer, ov->udp_len);
memcpy(from, ov->udp_sockaddr, *fromlen);