summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2004-04-08 11:52:37 +0000
committerbrain <brain@e03df62e-2008-0410-955e-edbf42e46eb7>2004-04-08 11:52:37 +0000
commit814b10681eb33bfa2796ef4fd21a354b8d27b0dc (patch)
tree1c6e6471d20982d2d7db3d8116dedb17cd9a5060
parent854dfb64572df12cda5deb47aff50bfd0b2882d2 (diff)
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
-rw-r--r--src/InspIRCd.dev12
-rw-r--r--src/InspIRCd.layout25
-rw-r--r--src/inspircd.cpp187
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 <vector>
#include <errno.h>
#include <deque>
+#include <errno.h>
#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);