diff options
-rw-r--r-- | include/inspircd.h | 4 | ||||
-rw-r--r-- | src/inspircd.cpp | 1 | ||||
-rw-r--r-- | src/userprocess.cpp | 46 |
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(); |