From 814b10681eb33bfa2796ef4fd21a354b8d27b0dc Mon Sep 17 00:00:00 2001 From: brain Date: Thu, 8 Apr 2004 11:52:37 +0000 Subject: Added connection pooling - connections are sorted into pools of X descriptors This is configurable, the default is 64 but it can go as high as the FD_MAX of the machine where its installed. git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@450 e03df62e-2008-0410-955e-edbf42e46eb7 --- src/InspIRCd.dev | 12 +++- src/InspIRCd.layout | 25 ++++--- src/inspircd.cpp | 187 ++++++++++++++++++++++++++++++++++------------------ 3 files changed, 150 insertions(+), 74 deletions(-) diff --git a/src/InspIRCd.dev b/src/InspIRCd.dev index 4f7a65363..c30d4d51e 100644 --- a/src/InspIRCd.dev +++ b/src/InspIRCd.dev @@ -1,7 +1,7 @@ [Project] FileName=InspIRCd.dev Name=InspIRCd -UnitCount=39 +UnitCount=40 Type=1 Ver=1 ObjFiles= @@ -433,3 +433,13 @@ Priority=1000 OverrideBuildCmd=0 BuildCmd= +[Unit40] +FileName=modules\m_helpop.cpp +CompileCpp=1 +Folder=Modules +Compile=1 +Link=1 +Priority=1000 +OverrideBuildCmd=0 +BuildCmd= + diff --git a/src/InspIRCd.layout b/src/InspIRCd.layout index 8b3fba399..75db52f51 100644 --- a/src/InspIRCd.layout +++ b/src/InspIRCd.layout @@ -13,10 +13,10 @@ LeftChar=1 [Editor_1] Open=1 Top=1 -CursorCol=91 -CursorRow=2991 -TopLine=2957 -LeftChar=11 +CursorCol=1 +CursorRow=5523 +TopLine=5458 +LeftChar=1 [Editor_2] Open=1 @@ -225,8 +225,8 @@ LeftChar=1 [Editor_28] Open=1 Top=0 -CursorCol=1 -CursorRow=24 +CursorCol=87 +CursorRow=20 TopLine=5 LeftChar=1 [Editor_29] @@ -239,10 +239,10 @@ LeftChar=1 [Editor_30] Open=1 Top=0 -CursorCol=1 -CursorRow=26 +CursorCol=87 +CursorRow=21 TopLine=1 -LeftChar=1 +LeftChar=4 [Editor_31] Open=1 Top=0 @@ -291,3 +291,10 @@ CursorCol=49 CursorRow=31 TopLine=1 LeftChar=1 +[Editor_39] +Open=1 +Top=0 +CursorCol=20 +CursorRow=84 +TopLine=13 +LeftChar=1 diff --git a/src/inspircd.cpp b/src/inspircd.cpp index 052cd1410..63ef005df 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -40,6 +40,7 @@ using namespace std; #include #include #include +#include #include "connection.h" #include "users.h" #include "servers.h" @@ -5228,7 +5229,7 @@ int InspIRCd(void) int openSockfd[MAXSOCKS], incomingSockfd, result = TRUE; socklen_t length; int count = 0, scanDetectTrigger = TRUE, showBanner = FALSE; - int selectResult = 0; + int selectResult = 0, selectResult2 = 0; char *temp, configToken[MAXBUF], stuff[MAXBUF], Addr[MAXBUF], Type[MAXBUF]; char resolvedHost[MAXBUF]; fd_set selectFds; @@ -5456,97 +5457,153 @@ int InspIRCd(void) } } } + + fd_set sfd; + struct timeval tval; - for (user_hash::iterator count2 = clientlist.begin(); count2 != clientlist.end(); count2++) + user_hash::iterator count2 = clientlist.begin(); + + while (count2 != clientlist.end()) { char data[MAXBUF]; + tval.tv_usec = tval.tv_sec = 0; + FD_ZERO(&sfd); + int total_in_this_set = 0; + + user_hash::iterator xcount = count2; + user_hash::iterator endingiter = count2; if (!count2->second) break; if (count2->second) if (count2->second->fd) { - // registration timeout -- didnt send USER/NICK/HOST in the time specified in - // their connection class. - if ((time(NULL) > count2->second->timeout) && (count2->second->registered != 7)) - { - log(DEBUG,"InspIRCd: registration timeout: %s",count2->second->nick); - kill_link(count2->second,"Registration timeout"); - break; - } - if (((time(NULL)) > count2->second->nping) && (isnick(count2->second->nick)) && (count2->second->registered == 7)) + // assemble up to 64 sockets into an fd_set + // to implement a pooling mechanism. + // + // This should be up to 64x faster than the + // old implementation. + while (total_in_this_set < 64) { - if (!count2->second->lastping) + if (count2 != clientlist.end()) { - log(DEBUG,"InspIRCd: ping timeout: %s",count2->second->nick); - kill_link(count2->second,"Ping timeout"); - break; + // registration timeout -- didnt send USER/NICK/HOST in the time specified in + // their connection class. + if ((time(NULL) > count2->second->timeout) && (count2->second->registered != 7)) + { + log(DEBUG,"InspIRCd: registration timeout: %s",count2->second->nick); + kill_link(count2->second,"Registration timeout"); + break; + } + if (((time(NULL)) > count2->second->nping) && (isnick(count2->second->nick)) && (count2->second->registered == 7)) + { + if (!count2->second->lastping) + { + log(DEBUG,"InspIRCd: ping timeout: %s",count2->second->nick); + kill_link(count2->second,"Ping timeout"); + break; + } + Write(count2->second->fd,"PING :%s",ServerName); + log(DEBUG,"InspIRCd: pinging: %s",count2->second->nick); + count2->second->lastping = 0; + count2->second->nping = time(NULL)+120; + } + + FD_SET (count2->second->fd, &sfd); + count2++; + total_in_this_set++; } - Write(count2->second->fd,"PING :%s",ServerName); - log(DEBUG,"InspIRCd: pinging: %s",count2->second->nick); - count2->second->lastping = 0; - count2->second->nping = time(NULL)+120; + else break; } + + endingiter = count2; + count2 = xcount; // roll back to where we were + + tval.tv_usec = 0; + tval.tv_sec = 0; + selectResult2 = select(total_in_this_set, &sfd, NULL, NULL, &tval); - result = read(count2->second->fd, data, 1); - // result EAGAIN means nothing read - if (result == EAGAIN) - { - } - else - if (result == 0) + // now loop through all of the items in this pool if any are waiting + //if (selectResult2 > 0) + for (user_hash::iterator count2a = xcount; count2a != endingiter; count2a++) { - if (count2->second) - { - log(DEBUG,"InspIRCd: Exited: %s",count2->second->nick); - kill_link(count2->second,"Client exited"); - // must bail here? kill_link removes the hash, corrupting the iterator - log(DEBUG,"Bailing from client exit"); - break; - } - } - else if (result > 0) - { - if (count2->second) + result = EAGAIN; + if (FD_ISSET (count2a->second->fd, &sfd)) { - - // until the buffer is at 509 chars anything can be inserted into it. - if ((strlen(count2->second->inbuf) < 509) && (data[0] != '\0')) { - strncat(count2->second->inbuf, data, result); + result = read(count2a->second->fd, data, 1); + if ((result == -1) && (errno != EAGAIN) && (errno != EINTR)) + { + kill_link(count2a->second,strerror(errno)); + goto label; } - - // once you reach 509 chars, only a \r or \n can be inserted, - // completing the line. - if ((strlen(count2->second->inbuf) >= 509) && ((data[0] == '\r') || (data[0] == '\n'))) { - count2->second->inbuf[509] = '\r'; - count2->second->inbuf[510] = '\n'; - count2->second->inbuf[511] = '\0'; - process_buffer(count2->second); - break; + } + // result EAGAIN means nothing read + if (result == EAGAIN) + { + } + else + if (result == 0) + { + if (count2->second) + { + log(DEBUG,"InspIRCd: Exited: %s",count2a->second->nick); + kill_link(count2a->second,"Client exited"); + // must bail here? kill_link removes the hash, corrupting the iterator + log(DEBUG,"Bailing from client exit"); + goto label; } - - if (strchr(count2->second->inbuf, '\n') || strchr(count2->second->inbuf, '\r') || (strlen(count2->second->inbuf) > 509)) + } + else if (result > 0) + { + if (count2a->second) { - /* at least one complete line is waiting to be processed */ - if (!count2->second->fd) - break; - else + + // until the buffer is at 509 chars anything can be inserted into it. + if ((strlen(count2a->second->inbuf) < 509) && (data[0] != '\0')) { + strncat(count2a->second->inbuf, data, result); + } + + // once you reach 509 chars, only a \r or \n can be inserted, + // completing the line. + if ((strlen(count2a->second->inbuf) >= 509) && ((data[0] == '\r') || (data[0] == '\n'))) { + count2a->second->inbuf[509] = '\r'; + count2a->second->inbuf[510] = '\n'; + count2a->second->inbuf[511] = '\0'; + process_buffer(count2a->second); + goto label; + } + + if (strchr(count2a->second->inbuf, '\n') || strchr(count2a->second->inbuf, '\r') || (strlen(count2a->second->inbuf) > 509)) { - if (strlen(count2->second->inbuf)<512) - { - // double check the length before processing! - process_buffer(count2->second); - } + /* at least one complete line is waiting to be processed */ + if (!count2a->second->fd) + goto label; else { - strcpy(count2->second->inbuf,""); + if (strlen(count2a->second->inbuf)<512) + { + // double check the length before processing! + process_buffer(count2a->second); + } + else + { + strcpy(count2a->second->inbuf,""); + } + goto label; } - break; } } } } } + for (int q = 0; q < total_in_this_set; q++) + { + // there is no iterator += operator :( + //if (count2 != clientlist.end()) + //{ + count2++; + //} + } } /* select is reporting a waiting socket. Poll them all to find out which */ @@ -5592,6 +5649,8 @@ int InspIRCd(void) } } } + label: + if(0) {}; // "Label must be followed by a statement"... so i gave it one. } /* not reached */ close (incomingSockfd); -- cgit v1.2.3