summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/dns.h11
-rw-r--r--include/inspircd.h15
-rw-r--r--src/configreader.cpp2
-rw-r--r--src/dns.cpp19
-rw-r--r--src/inspircd.cpp61
-rw-r--r--src/modules/m_spanningtree/main.cpp4
-rw-r--r--src/modules/m_spanningtree/pong.cpp8
-rw-r--r--src/modules/m_spanningtree/treeserver.cpp8
-rw-r--r--src/modules/m_spanningtree/treeserver.h2
-rw-r--r--src/socketengines/socketengine_epoll.cpp1
-rw-r--r--src/socketengines/socketengine_kqueue.cpp1
-rw-r--r--src/socketengines/socketengine_poll.cpp1
-rw-r--r--src/socketengines/socketengine_ports.cpp1
-rw-r--r--src/socketengines/socketengine_select.cpp1
-rw-r--r--src/stats.cpp5
-rw-r--r--src/userprocess.cpp8
-rw-r--r--win/inspircd_win32wrapper.cpp4
-rw-r--r--win/inspircd_win32wrapper.h3
18 files changed, 76 insertions, 79 deletions
diff --git a/include/dns.h b/include/dns.h
index f79121ab3..3d326a69c 100644
--- a/include/dns.h
+++ b/include/dns.h
@@ -84,19 +84,12 @@ class CoreExport CachedQuery
* @param res The result data, an IP or hostname
* @param ttl The time-to-live value of the query result
*/
- CachedQuery(const std::string &res, unsigned int ttl) : data(res)
- {
- expires = time(NULL) + ttl;
- }
+ CachedQuery(const std::string &res, unsigned int ttl);
/** Returns the number of seconds remaining before this
* cache item has expired and should be removed.
*/
- int CalcTTLRemaining()
- {
- int n = (int)expires - (int)time(NULL);
- return (n < 0 ? 0 : n);
- }
+ int CalcTTLRemaining();
};
/** DNS cache information. Holds IPs mapped to hostnames, and hostnames mapped to IPs.
diff --git a/include/inspircd.h b/include/inspircd.h
index 3d1abdee4..89f0a08ee 100644
--- a/include/inspircd.h
+++ b/include/inspircd.h
@@ -52,6 +52,7 @@
#include <map>
#include <bitset>
#include <set>
+#include <time.h>
#include "inspircd_config.h"
#include "inspircd_version.h"
#include "typedefs.h"
@@ -222,7 +223,7 @@ class serverstats
timeval LastCPU;
/** Time last sample was read
*/
- timeval LastSampled;
+ timespec LastSampled;
/** The constructor initializes all the counts to zero
*/
serverstats()
@@ -282,11 +283,7 @@ class CoreExport InspIRCd
/** The current time, updated in the mainloop
*/
- time_t TIME;
-
- /** The time that was recorded last time around the mainloop
- */
- time_t OLDTIME;
+ struct timespec TIME;
/** A 64k buffer used to read socket data into
* NOTE: update ValidateNetBufferSize if you change this
@@ -446,7 +443,11 @@ class CoreExport InspIRCd
* it is much faster than calling time() directly.
* @return The current time as an epoch value (time_t)
*/
- time_t Time();
+ inline time_t Time() { return TIME.tv_sec; }
+ /** The fractional time at the start of this mainloop iteration (nanoseconds) */
+ inline long Time_ns() { return TIME.tv_nsec; }
+ /** Update the current time. Don't call this unless you have reason to do so. */
+ void UpdateTime();
/** Bind all ports specified in the configuration file.
* @return The number of ports bound without error
diff --git a/src/configreader.cpp b/src/configreader.cpp
index c62973c89..156168bbe 100644
--- a/src/configreader.cpp
+++ b/src/configreader.cpp
@@ -872,7 +872,7 @@ void ConfigReaderThread::Finish()
ServerInstance->Res->Rehash();
ServerInstance->ResetMaxBans();
Config->ApplyDisabledCommands(Config->DisabledCommands);
- User* user = TheUserUID.empty() ? ServerInstance->FindNick(TheUserUID) : NULL;
+ User* user = ServerInstance->FindNick(TheUserUID);
FOREACH_MOD(I_OnRehash, OnRehash(user));
ServerInstance->BuildISupport();
diff --git a/src/dns.cpp b/src/dns.cpp
index ba1e8f2a4..dee83d3ac 100644
--- a/src/dns.cpp
+++ b/src/dns.cpp
@@ -147,6 +147,17 @@ class RequestTimeout : public Timer
}
};
+CachedQuery::CachedQuery(const std::string &res, unsigned int ttl) : data(res)
+{
+ expires = ServerInstance->Time() + ttl;
+}
+
+int CachedQuery::CalcTTLRemaining()
+{
+ int n = expires - ServerInstance->Time();
+ return (n < 0 ? 0 : n);
+}
+
/* Allocate the processing buffer */
DNSRequest::DNSRequest(DNS* dns, int rid, const std::string &original) : dnsobj(dns)
{
@@ -1035,11 +1046,9 @@ void DNS::CleanResolvers(Module* module)
unsigned long DNS::PRNG()
{
unsigned long val = 0;
- timeval n;
serverstats* s = ServerInstance->stats;
- gettimeofday(&n,NULL);
- val = (n.tv_usec ^ (getpid() ^ geteuid()) ^ ((this->currid++)) ^ s->statsAccept) + n.tv_sec;
- val = val + (s->statsCollisions ^ s->statsDnsGood) - s->statsDnsBad;
- val += (s->statsConnects ^ (unsigned long)s->statsSent ^ (unsigned long)s->statsRecv) - ServerInstance->ports.size();
+ val = (rand() ^ this->currid++ ^ s->statsAccept) + ServerInstance->Time_ns();
+ val += (s->statsCollisions ^ s->statsDnsGood) * s->statsDnsBad;
+ val += (s->statsConnects ^ (unsigned long)s->statsSent ^ (unsigned long)s->statsRecv);
return val;
}
diff --git a/src/inspircd.cpp b/src/inspircd.cpp
index 8cead1c87..47f743df2 100644
--- a/src/inspircd.cpp
+++ b/src/inspircd.cpp
@@ -340,7 +340,8 @@ InspIRCd::InspIRCd(int argc, char** argv) :
this->ConfigThread = NULL;
// Initialise TIME
- this->TIME = this->OLDTIME = this->startup_time = time(NULL);
+ clock_gettime(CLOCK_REALTIME, &TIME);
+ this->startup_time = TIME.tv_sec;
// This must be created first, so other parts of Insp can use it while starting up
this->Logs = new LogManager;
@@ -375,7 +376,7 @@ InspIRCd::InspIRCd(int argc, char** argv) :
this->Config->cmdline.argv = argv;
this->Config->cmdline.argc = argc;
- srand(this->TIME);
+ srand(TIME.tv_nsec ^ TIME.tv_sec);
struct option longopts[] =
{
@@ -685,6 +686,11 @@ InspIRCd::InspIRCd(int argc, char** argv) :
this->WritePID(Config->PID);
}
+void InspIRCd::UpdateTime()
+{
+ clock_gettime(CLOCK_REALTIME, &TIME);
+}
+
int InspIRCd::Run()
{
/* See if we're supposed to be running the test suite rather than entering the mainloop */
@@ -695,6 +701,9 @@ int InspIRCd::Run()
Exit(0);
}
+ UpdateTime();
+ time_t OLDTIME = TIME.tv_sec;
+
while (true)
{
#ifndef WIN32
@@ -718,53 +727,48 @@ int InspIRCd::Run()
ConfigThread = NULL;
}
- /* time() seems to be a pretty expensive syscall, so avoid calling it too much.
- * Once per loop iteration is pleanty.
- */
- OLDTIME = TIME;
- TIME = time(NULL);
+ UpdateTime();
/* Run background module timers every few seconds
* (the docs say modules shouldnt rely on accurate
* timing using this event, so we dont have to
* time this exactly).
*/
- if (TIME != OLDTIME)
+ if (TIME.tv_sec != OLDTIME)
{
+ OLDTIME = TIME.tv_sec;
+#ifndef WIN32
+ getrusage(RUSAGE_SELF, &ru);
+ stats->LastSampled = TIME;
+ stats->LastCPU = ru.ru_utime;
+#else
+ WindowsIPC->Check();
+#endif
+
/* Allow a buffer of two seconds drift on this so that ntpdate etc dont harass admins */
- if (TIME < OLDTIME - 2)
+ if (TIME.tv_sec < OLDTIME - 2)
{
- SNO->WriteToSnoMask('d', "\002EH?!\002 -- Time is flowing BACKWARDS in this dimension! Clock drifted backwards %lu secs.", (unsigned long)OLDTIME-TIME);
+ SNO->WriteToSnoMask('d', "\002EH?!\002 -- Time is flowing BACKWARDS in this dimension! Clock drifted backwards %lu secs.", (unsigned long)OLDTIME-TIME.tv_sec);
}
- else if (TIME > OLDTIME + 2)
+ else if (TIME.tv_sec > OLDTIME + 2)
{
- SNO->WriteToSnoMask('d', "\002EH?!\002 -- Time is jumping FORWARDS! Clock skipped %lu secs.", (unsigned long)TIME - OLDTIME);
+ SNO->WriteToSnoMask('d', "\002EH?!\002 -- Time is jumping FORWARDS! Clock skipped %lu secs.", (unsigned long)TIME.tv_sec - OLDTIME);
}
- if ((TIME % 3600) == 0)
+ if ((TIME.tv_sec % 3600) == 0)
{
this->RehashUsersAndChans();
FOREACH_MOD(I_OnGarbageCollect, OnGarbageCollect());
}
- Timers->TickTimers(TIME);
+ Timers->TickTimers(TIME.tv_sec);
this->DoBackgroundUserStuff();
- if ((TIME % 5) == 0)
+ if ((TIME.tv_sec % 5) == 0)
{
- FOREACH_MOD(I_OnBackgroundTimer,OnBackgroundTimer(TIME));
+ FOREACH_MOD(I_OnBackgroundTimer,OnBackgroundTimer(TIME.tv_sec));
SNO->FlushSnotices();
}
-#ifndef WIN32
- /* Same change as in cmd_stats.cpp, use RUSAGE_SELF rather than '0' -- Om */
- if (!getrusage(RUSAGE_SELF, &ru))
- {
- gettimeofday(&this->stats->LastSampled, NULL);
- this->stats->LastCPU = ru.ru_utime;
- }
-#else
- WindowsIPC->Check();
-#endif
}
/* Call the socket engine to wait on the active
@@ -808,11 +812,6 @@ bool InspIRCd::AllModulesReportReady(LocalUser* user)
return (res == MOD_RES_PASSTHRU);
}
-time_t InspIRCd::Time()
-{
- return TIME;
-}
-
void InspIRCd::SetSignal(int signal)
{
*mysig = signal;
diff --git a/src/modules/m_spanningtree/main.cpp b/src/modules/m_spanningtree/main.cpp
index 4961d724b..18f399bbf 100644
--- a/src/modules/m_spanningtree/main.cpp
+++ b/src/modules/m_spanningtree/main.cpp
@@ -128,9 +128,7 @@ void ModuleSpanningTree::DoPingChecks(time_t curtime)
* Cancel remote burst mode on any servers which still have it enabled due to latency/lack of data.
* This prevents lost REMOTECONNECT notices
*/
- timeval t;
- gettimeofday(&t, NULL);
- long ts = (t.tv_sec * 1000) + (t.tv_usec / 1000);
+ long ts = ServerInstance->Time() * 1000 + (ServerInstance->Time_ns() / 1000000);
for (server_hash::iterator i = Utils->serverlist.begin(); i != Utils->serverlist.end(); i++)
{
diff --git a/src/modules/m_spanningtree/pong.cpp b/src/modules/m_spanningtree/pong.cpp
index dd82f7d86..9627da8c0 100644
--- a/src/modules/m_spanningtree/pong.cpp
+++ b/src/modules/m_spanningtree/pong.cpp
@@ -34,9 +34,7 @@ bool TreeSocket::LocalPong(const std::string &prefix, parameterlist &params)
if (ServerSource)
{
ServerSource->SetPingFlag();
- timeval t;
- gettimeofday(&t, NULL);
- long ts = (t.tv_sec * 1000) + (t.tv_usec / 1000);
+ long ts = ServerInstance->Time() * 1000 + (ServerInstance->Time_ns() / 1000000);
ServerSource->rtt = ts - ServerSource->LastPingMsec;
}
}
@@ -61,9 +59,7 @@ bool TreeSocket::LocalPong(const std::string &prefix, parameterlist &params)
if (ServerSource)
{
- timeval t;
- gettimeofday(&t, NULL);
- long ts = (t.tv_sec * 1000) + (t.tv_usec / 1000);
+ long ts = ServerInstance->Time() * 1000 + (ServerInstance->Time_ns() / 1000000);
ServerSource->rtt = ts - ServerSource->LastPingMsec;
ServerSource->SetPingFlag();
}
diff --git a/src/modules/m_spanningtree/treeserver.cpp b/src/modules/m_spanningtree/treeserver.cpp
index d5c3927f9..00799aa8e 100644
--- a/src/modules/m_spanningtree/treeserver.cpp
+++ b/src/modules/m_spanningtree/treeserver.cpp
@@ -59,9 +59,7 @@ TreeServer::TreeServer(SpanningTreeUtilities* Util, std::string Name, std::strin
Warned = false;
rtt = 0;
- timeval t;
- gettimeofday(&t, NULL);
- long ts = (t.tv_sec * 1000) + (t.tv_usec / 1000);
+ long ts = ServerInstance->Time() * 1000 + (ServerInstance->Time_ns() / 1000000);
this->StartBurst = ts;
ServerInstance->Logs->Log("m_spanningtree",DEBUG, "Started bursting at time %lu", ts);
@@ -142,9 +140,7 @@ void TreeServer::FinishBurst()
{
FinishBurstInternal();
ServerInstance->XLines->ApplyLines();
- timeval t;
- gettimeofday(&t, NULL);
- long ts = (t.tv_sec * 1000) + (t.tv_usec / 1000);
+ long ts = ServerInstance->Time() * 1000 + (ServerInstance->Time_ns() / 1000000);
unsigned long bursttime = ts - this->StartBurst;
ServerInstance->SNO->WriteToSnoMask(Parent == Utils->TreeRoot ? 'l' : 'L', "Received end of netburst from \2%s\2 (burst time: %lu %s)",
ServerName.c_str(), (bursttime > 10000 ? bursttime / 1000 : bursttime), (bursttime > 10000 ? "secs" : "msecs"));
diff --git a/src/modules/m_spanningtree/treeserver.h b/src/modules/m_spanningtree/treeserver.h
index 9520506ae..079b6535e 100644
--- a/src/modules/m_spanningtree/treeserver.h
+++ b/src/modules/m_spanningtree/treeserver.h
@@ -109,7 +109,7 @@ class TreeServer : public classbase
*/
time_t NextPingTime();
- /** Last ping time in microseconds, used to calculate round trip time
+ /** Last ping time in milliseconds, used to calculate round trip time
*/
unsigned long LastPingMsec;
diff --git a/src/socketengines/socketengine_epoll.cpp b/src/socketengines/socketengine_epoll.cpp
index 11fa72072..96c3922f9 100644
--- a/src/socketengines/socketengine_epoll.cpp
+++ b/src/socketengines/socketengine_epoll.cpp
@@ -187,6 +187,7 @@ int EPollEngine::DispatchEvents()
socklen_t codesize = sizeof(int);
int errcode;
int i = epoll_wait(EngineHandle, events, GetMaxFds() - 1, 1000);
+ ServerInstance->UpdateTime();
TotalEvents += i;
diff --git a/src/socketengines/socketengine_kqueue.cpp b/src/socketengines/socketengine_kqueue.cpp
index ca909ce3e..e7d7e4283 100644
--- a/src/socketengines/socketengine_kqueue.cpp
+++ b/src/socketengines/socketengine_kqueue.cpp
@@ -217,6 +217,7 @@ int KQueueEngine::DispatchEvents()
ts.tv_sec = 1;
int i = kevent(EngineHandle, NULL, 0, &ke_list[0], GetMaxFds(), &ts);
+ ServerInstance->UpdateTime();
TotalEvents += i;
diff --git a/src/socketengines/socketengine_poll.cpp b/src/socketengines/socketengine_poll.cpp
index f30cd1fed..93463aea7 100644
--- a/src/socketengines/socketengine_poll.cpp
+++ b/src/socketengines/socketengine_poll.cpp
@@ -235,6 +235,7 @@ int PollEngine::DispatchEvents()
socklen_t codesize = sizeof(int);
int errcode;
int processed = 0;
+ ServerInstance->UpdateTime();
if (i > 0)
{
diff --git a/src/socketengines/socketengine_ports.cpp b/src/socketengines/socketengine_ports.cpp
index 43d958173..23a3c3a45 100644
--- a/src/socketengines/socketengine_ports.cpp
+++ b/src/socketengines/socketengine_ports.cpp
@@ -167,6 +167,7 @@ int PortsEngine::DispatchEvents()
unsigned int nget = 1; // used to denote a retrieve request.
int i = port_getn(EngineHandle, this->events, GetMaxFds() - 1, &nget, &poll_time);
+ ServerInstance->UpdateTime();
// first handle an error condition
if (i == -1)
diff --git a/src/socketengines/socketengine_select.cpp b/src/socketengines/socketengine_select.cpp
index 7bff4ff6d..795e844e6 100644
--- a/src/socketengines/socketengine_select.cpp
+++ b/src/socketengines/socketengine_select.cpp
@@ -119,6 +119,7 @@ int SelectEngine::DispatchEvents()
tval.tv_usec = 0;
sresult = select(FD_SETSIZE, &rfdset, &wfdset, &errfdset, &tval);
+ ServerInstance->UpdateTime();
/* Nothing to process this time around */
if (sresult < 1)
diff --git a/src/stats.cpp b/src/stats.cpp
index b295db4a5..b272e0b6b 100644
--- a/src/stats.cpp
+++ b/src/stats.cpp
@@ -194,11 +194,10 @@ void InspIRCd::DoStats(char statschar, User* user, string_list &results)
results.push_back(sn+" 249 "+user->nick+" :Swaps: "+ConvToStr(R.ru_nswap));
results.push_back(sn+" 249 "+user->nick+" :Context Switches: Voluntary; "+ConvToStr(R.ru_nvcsw)+" Involuntary; "+ConvToStr(R.ru_nivcsw));
- timeval tv;
char percent[30];
- gettimeofday(&tv, NULL);
- float n_elapsed = ((tv.tv_sec - this->stats->LastSampled.tv_sec) * 1000000 + tv.tv_usec - this->stats->LastSampled.tv_usec);
+ float n_elapsed = (ServerInstance->Time() - this->stats->LastSampled.tv_sec) * 1000000
+ + (ServerInstance->Time_ns() - this->stats->LastSampled.tv_nsec) / 1000;
float n_eaten = ((R.ru_utime.tv_sec - this->stats->LastCPU.tv_sec) * 1000000 + R.ru_utime.tv_usec - this->stats->LastCPU.tv_usec);
float per = (n_eaten / n_elapsed) * 100;
diff --git a/src/userprocess.cpp b/src/userprocess.cpp
index 75cd8634a..ee9c75bc0 100644
--- a/src/userprocess.cpp
+++ b/src/userprocess.cpp
@@ -68,7 +68,7 @@ void InspIRCd::DoBackgroundUserStuff()
switch (curr->registered)
{
case REG_ALL:
- if (TIME > curr->nping)
+ if (Time() > curr->nping)
{
// This user didn't answer the last ping, remove them
if (!curr->lastping)
@@ -77,14 +77,14 @@ void InspIRCd::DoBackgroundUserStuff()
char message[MAXBUF];
snprintf(message, MAXBUF, "Ping timeout: %ld second%s", (long)time, time > 1 ? "s" : "");
curr->lastping = 1;
- curr->nping = TIME + curr->MyClass->GetPingTime();
+ curr->nping = Time() + curr->MyClass->GetPingTime();
this->Users->QuitUser(curr, message);
continue;
}
curr->Write("PING :%s",this->Config->ServerName.c_str());
curr->lastping = 0;
- curr->nping = TIME +curr->MyClass->GetPingTime();
+ curr->nping = Time() +curr->MyClass->GetPingTime();
}
break;
case REG_NICKUSER:
@@ -97,7 +97,7 @@ void InspIRCd::DoBackgroundUserStuff()
break;
}
- if (curr->registered != REG_ALL && (TIME > (curr->age + curr->MyClass->GetRegTimeout())))
+ if (curr->registered != REG_ALL && (Time() > (curr->age + curr->MyClass->GetRegTimeout())))
{
/*
* registration timeout -- didnt send USER/NICK/HOST
diff --git a/win/inspircd_win32wrapper.cpp b/win/inspircd_win32wrapper.cpp
index 8291cd60d..d82c90a61 100644
--- a/win/inspircd_win32wrapper.cpp
+++ b/win/inspircd_win32wrapper.cpp
@@ -549,14 +549,14 @@ void FindDNS(std::string& server)
ServerInstance->Logs->Log("CONFIG",DEFAULT,"<dns:server> set to '%s' as first active resolver in registry.", nameserver.c_str());
}
-int gettimeofday(struct timeval * tv, void * tz)
+int clock_gettime(int clock, struct timespec * tv)
{
if(tv == NULL)
return -1;
DWORD mstime = timeGetTime();
tv->tv_sec = time(NULL);
- tv->tv_usec = (mstime - (tv->tv_sec * 1000)) * 1000;
+ tv->tv_usec = (mstime - (tv->tv_sec * 1000)) * 1000000;
return 0;
}
diff --git a/win/inspircd_win32wrapper.h b/win/inspircd_win32wrapper.h
index 4397d2ad3..3f16280fd 100644
--- a/win/inspircd_win32wrapper.h
+++ b/win/inspircd_win32wrapper.h
@@ -193,7 +193,8 @@ CoreExport DIR * opendir(const char * path);
CoreExport dirent * readdir(DIR * handle);
CoreExport void closedir(DIR * handle);
-CoreExport int gettimeofday(struct timeval * tv, void * tz);
+const int CLOCK_REALTIME = 0;
+CoreExport int clock_gettime(int clock, struct timespec * tv);
/* Disable these stupid warnings.. */
#pragma warning(disable:4800)