summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/inspircd.h4
-rw-r--r--src/inspircd.cpp1
-rw-r--r--src/userprocess.cpp46
3 files changed, 49 insertions, 2 deletions
diff --git a/include/inspircd.h b/include/inspircd.h
index 8c897305f..16b42e50b 100644
--- a/include/inspircd.h
+++ b/include/inspircd.h
@@ -421,6 +421,10 @@ class InspIRCd : public classbase
*/
FactoryList factory;
+ /** The time we next call our ping timeout and reg timeout checks
+ */
+ time_t next_call;
+
/** Get the current time
* Because this only calls time() once every time around the mainloop,
* it is much faster than calling time() directly.
diff --git a/src/inspircd.cpp b/src/inspircd.cpp
index 2f44e9735..53f3bb733 100644
--- a/src/inspircd.cpp
+++ b/src/inspircd.cpp
@@ -190,6 +190,7 @@ InspIRCd::InspIRCd(int argc, char** argv)
this->SNO = new SnomaskManager(this);
this->Start();
this->TIME = this->OLDTIME = this->startup_time = time(NULL);
+ this->next_call = this->TIME + 3;
srand(this->TIME);
this->Log(DEBUG,"*** InspIRCd starting up!");
if (!ServerConfig::FileExists(CONFIG_FILE))
diff --git a/src/userprocess.cpp b/src/userprocess.cpp
index cb204989d..327cd88f3 100644
--- a/src/userprocess.cpp
+++ b/src/userprocess.cpp
@@ -245,8 +245,16 @@ void InspIRCd::ProcessUser(userrec* cu)
*/
void InspIRCd::DoBackgroundUserStuff(time_t TIME)
{
+ /* Is it time yet? */
+ if (TIME < next_call)
+ return;
+
CullList GlobalGoners(this);
+ /* Time we actually need to call this again */
+ const time_t DUMMY_VALUE = 32768;
+ next_call = TIME + DUMMY_VALUE;
+
/* XXX: IT IS NOT SAFE TO USE AN ITERATOR HERE. DON'T EVEN THINK ABOUT IT. */
for (unsigned long count2 = 0; count2 != this->local_users.size(); count2++)
{
@@ -268,11 +276,18 @@ void InspIRCd::DoBackgroundUserStuff(time_t TIME)
GlobalGoners.AddItem(curr,"Registration timeout");
continue;
}
+ else
+ {
+ if ((curr->registered != REG_ALL) && (next_call > (time_t)curr->timeout))
+ next_call = curr->timeout;
+ }
+
/*
* user has signed on with USER/NICK/PASS, and dns has completed, all the modules
* say this user is ok to proceed, fully connect them.
*/
- if ((TIME > curr->signon) && (curr->registered == REG_NICKUSER) && (AllModulesReportReady(curr)))
+ bool ready = AllModulesReportReady(curr);
+ if ((TIME > curr->signon) && (curr->registered == REG_NICKUSER) && (ready))
{
curr->dns_done = true;
//ZapThisDns(curr->fd);
@@ -280,13 +295,25 @@ void InspIRCd::DoBackgroundUserStuff(time_t TIME)
curr->FullConnect(&GlobalGoners);
continue;
}
- if ((curr->dns_done) && (curr->registered == REG_NICKUSER) && (AllModulesReportReady(curr)))
+ else
+ {
+ if ((curr->registered == REG_NICKUSER) && (ready) && (next_call > curr->signon))
+ next_call = curr->signon;
+ }
+
+ if ((curr->dns_done) && (curr->registered == REG_NICKUSER) && (ready))
{
this->Log(DEBUG,"dns done, registered=3, and modules ready, OK");
curr->FullConnect(&GlobalGoners);
//ZapThisDns(curr->fd);
continue;
}
+ else
+ {
+ if ((curr->registered == REG_NICKUSER) && (ready) && (next_call > curr->signon + this->Config->dns_timeout))
+ next_call = curr->signon + this->Config->dns_timeout;
+ }
+
// It's time to PING this user. Send them a ping.
if ((TIME > curr->nping) && (curr->registered == REG_ALL))
{
@@ -305,6 +332,11 @@ void InspIRCd::DoBackgroundUserStuff(time_t TIME)
curr->lastping = 0;
curr->nping = TIME+curr->pingmax;
}
+ else
+ {
+ if ((curr->registered == REG_ALL) && (next_call > curr->nping))
+ next_call = curr->nping;
+ }
/*
* We can flush the write buffer as the last thing we do, because if they
@@ -321,6 +353,16 @@ void InspIRCd::DoBackgroundUserStuff(time_t TIME)
}
+ /* If theres nothing to do, trigger in the next second, something might come up */
+ time_t delta = next_call - TIME;
+ if (delta == DUMMY_VALUE)
+ {
+ next_call = TIME + 1;
+ delta = 1;
+ }
+
+ this->Log(DEBUG,"Time now is %lu, next time we actually need to call this is %lu (%lu secs from now)", TIME, next_call, delta);
+
/* Remove all the queued users who are due to be quit, free memory used. */
GlobalGoners.Apply();