void TreeServer::FinishBurstInternal() { this->bursting = false; SetNextPingTime(ServerInstance->Time() + Utils->PingFreq); SetPingFlag(); for (ChildServers::const_iterator i = Children.begin(); i != Children.end(); ++i) { TreeServer* child = *i; child->FinishBurstInternal(); } }
void TreeServer::FinishBurstInternal() { this->bursting = false; SetNextPingTime(ServerInstance->Time() + Utils->PingFreq); SetPingFlag(); for(unsigned int q=0; q < ChildCount(); q++) { TreeServer* child = GetChild(q); child->FinishBurstInternal(); } }
/** When we create a new server, we call this constructor to initialize it. * This constructor initializes the server's Route and Parent, and sets up * its ping counters so that it will be pinged one minute from now. */ TreeServer::TreeServer(const std::string& Name, const std::string& Desc, const std::string& id, TreeServer* Above, TreeSocket* Sock, bool Hide) : Server(Name, Desc) , Parent(Above), Socket(Sock), sid(id), ServerUser(new FakeUser(id, this)) , age(ServerInstance->Time()), Warned(false), bursting(true), UserCount(0), OperCount(0), rtt(0), Hidden(Hide) { CheckULine(); SetNextPingTime(ServerInstance->Time() + Utils->PingFreq); SetPingFlag(); long ts = ServerInstance->Time() * 1000 + (ServerInstance->Time_ns() / 1000000); this->StartBurst = ts; ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Server %s started bursting at time %lu", sid.c_str(), ts); /* find the 'route' for this server (e.g. the one directly connected * to the local server, which we can use to reach it) * * In the following example, consider we have just added a TreeServer * class for server G on our network, of which we are server A. * To route traffic to G (marked with a *) we must send the data to * B (marked with a +) so this algorithm initializes the 'Route' * value to point at whichever server traffic must be routed through * to get here. If we were to try this algorithm with server B, * the Route pointer would point at its own object ('this'). * * A * / \ * + B C * / \ \ * D E F * / \ * * G H * * We only run this algorithm when a server is created, as * the routes remain constant while ever the server exists, and * do not need to be re-calculated. */ Route = Above; if (Route == Utils->TreeRoot) { Route = this; } else { while (this->Route->GetParent() != Utils->TreeRoot) { this->Route = Route->GetParent(); } } /* Because recursive code is slow and takes a lot of resources, * we store two representations of the server tree. The first * is a recursive structure where each server references its * children and its parent, which is used for netbursts and * netsplits to dump the whole dataset to the other server, * and the second is used for very fast lookups when routing * messages and is instead a hash_map, where each item can * be referenced by its server name. The AddHashEntry() * call below automatically inserts each TreeServer class * into the hash_map as it is created. There is a similar * maintainance call in the destructor to tidy up deleted * servers. */ this->AddHashEntry(); }