summaryrefslogtreecommitdiff
path: root/node/Node.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'node/Node.cpp')
-rw-r--r--node/Node.cpp41
1 files changed, 27 insertions, 14 deletions
diff --git a/node/Node.cpp b/node/Node.cpp
index 830ee354..85029e81 100644
--- a/node/Node.cpp
+++ b/node/Node.cpp
@@ -74,8 +74,9 @@ struct _NodeImpl
RuntimeEnvironment renv;
std::string reasonForTerminationStr;
Node::ReasonForTermination reasonForTermination;
- bool started;
- bool running;
+ volatile bool started;
+ volatile bool running;
+ volatile bool updateStatusNow;
volatile bool terminateNow;
// Helper used to rapidly terminate from run()
@@ -104,6 +105,7 @@ Node::Node(const char *hp,const char *urlPrefix,const char *configAuthorityIdent
impl->reasonForTermination = Node::NODE_RUNNING;
impl->started = false;
impl->running = false;
+ impl->updateStatusNow = false;
impl->terminateNow = false;
}
@@ -236,6 +238,8 @@ Node::ReasonForTermination Node::run()
}
try {
+ std::string statusPath(_r->homePath + ZT_PATH_SEPARATOR_S + "status");
+
uint64_t lastPingCheck = 0;
uint64_t lastTopologyClean = Utils::now(); // don't need to do this immediately
uint64_t lastNetworkFingerprintCheck = 0;
@@ -243,6 +247,7 @@ Node::ReasonForTermination Node::run()
uint64_t networkConfigurationFingerprint = _r->sysEnv->getNetworkConfigurationFingerprint();
uint64_t lastMulticastCheck = 0;
uint64_t lastMulticastAnnounceAll = 0;
+ uint64_t lastStatusUpdate = 0;
long lastDelayDelta = 0;
LOG("%s starting version %s",_r->identity.address().toString().c_str(),versionString());
@@ -373,6 +378,20 @@ Node::ReasonForTermination Node::run()
_r->topology->clean(); // happens in background
}
+ if (((now - lastStatusUpdate) >= ZT_STATUS_OUTPUT_PERIOD)||(impl->updateStatusNow)) {
+ lastStatusUpdate = now;
+ impl->updateStatusNow = false;
+ FILE *statusf = ::fopen(statusPath.c_str(),"w");
+ if (statusf) {
+ try {
+ _r->topology->eachPeer(Topology::DumpPeerStatistics(statusf));
+ } catch ( ... ) {
+ TRACE("unexpected exception updating status dump");
+ }
+ ::fclose(statusf);
+ }
+ }
+
try {
unsigned long delay = std::min((unsigned long)ZT_MIN_SERVICE_LOOP_INTERVAL,_r->sw->doTimerTasks());
uint64_t start = Utils::now();
@@ -391,11 +410,6 @@ Node::ReasonForTermination Node::run()
return impl->terminateBecause(Node::NODE_NORMAL_TERMINATION,"normal termination");
}
-/**
- * Obtain a human-readable reason for node termination
- *
- * @return Reason for node termination or NULL if run() has not returned
- */
const char *Node::reasonForTermination() const
throw()
{
@@ -404,19 +418,18 @@ const char *Node::reasonForTermination() const
return ((_NodeImpl *)_impl)->reasonForTerminationStr.c_str();
}
-/**
- * Cause run() to return with NODE_NORMAL_TERMINATION
- *
- * This can be called from a signal handler or another thread to signal a
- * running node to shut down. Shutdown may take a few seconds, so run()
- * may not return instantly. Multiple calls are ignored.
- */
void Node::terminate()
throw()
{
((_NodeImpl *)_impl)->terminateNow = true;
}
+void Node::updateStatusNow()
+ throw()
+{
+ ((_NodeImpl *)_impl)->updateStatusNow = true;
+}
+
class _VersionStringMaker
{
public: