From 01a70d09db917ce475120854514ee48af43cc1b1 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Tue, 27 Aug 2013 18:00:07 -0400 Subject: [PATCH] Jigger with shutdown method to avoid a crash on CTRL+C in Windows. Feels a big hacky, might revisit later. --- node/Demarc.cpp | 3 ++- node/Network.cpp | 2 ++ node/Node.cpp | 48 +++++++++++++++---------------------- node/RuntimeEnvironment.hpp | 5 +++- 4 files changed, 27 insertions(+), 31 deletions(-) diff --git a/node/Demarc.cpp b/node/Demarc.cpp index 0bb1646d4..ddbed6c84 100644 --- a/node/Demarc.cpp +++ b/node/Demarc.cpp @@ -210,7 +210,8 @@ Demarc::Port Demarc::send(Demarc::Port fromPort,const InetAddress &to,const void void Demarc::_CBudpSocketPacketHandler(UdpSocket *sock,void *arg,const InetAddress &from,const void *data,unsigned int len) { - ((DemarcPortObj *)arg)->parent->_r->sw->onRemotePacket(((DemarcPortObj *)arg)->port,from,Buffer<4096>(data,len)); + if (!((DemarcPortObj *)arg)->parent->_r->shutdownInProgress) + ((DemarcPortObj *)arg)->parent->_r->sw->onRemotePacket(((DemarcPortObj *)arg)->port,from,Buffer<4096>(data,len)); } } // namespace ZeroTier diff --git a/node/Network.cpp b/node/Network.cpp index 730e86d21..1e436a27d 100644 --- a/node/Network.cpp +++ b/node/Network.cpp @@ -282,6 +282,8 @@ void Network::_CBhandleTapData(void *arg,const MAC &from,const MAC &to,unsigned if (!((Network *)arg)->_ready) return; const RuntimeEnvironment *_r = ((Network *)arg)->_r; + if (_r->shutdownInProgress) + return; try { _r->sw->onLocalEthernet(SharedPtr((Network *)arg),from,to,etherType,data); } catch (std::exception &exc) { diff --git a/node/Node.cpp b/node/Node.cpp index c9aef8a5c..785fc6345 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -188,15 +188,31 @@ struct _NodeImpl volatile bool running; volatile bool terminateNow; - // Helper used to rapidly terminate from run() + // run() calls this on all return paths inline Node::ReasonForTermination terminateBecause(Node::ReasonForTermination r,const char *rstr) { RuntimeEnvironment *_r = &renv; LOG("terminating: %s",rstr); + renv.shutdownInProgress = true; + Thread::sleep(500); + +#ifndef __WINDOWS__ + delete renv.netconfService; +#endif + delete renv.nc; + delete renv.sysEnv; + delete renv.topology; + delete renv.demarc; + delete renv.sw; + delete renv.multicaster; + delete renv.prng; + delete renv.log; + reasonForTerminationStr = rstr; reasonForTermination = r; running = false; + return r; } }; @@ -257,7 +273,6 @@ Node::Node(const char *hp) _impl(new _NodeImpl) { _NodeImpl *impl = (_NodeImpl *)_impl; - if ((hp)&&(strlen(hp) > 0)) impl->renv.homePath = hp; else impl->renv.homePath = ZT_DEFAULTS.defaultHomePath; @@ -269,34 +284,9 @@ Node::Node(const char *hp) Node::~Node() { - _NodeImpl *impl = (_NodeImpl *)_impl; - -#ifndef __WINDOWS__ - delete impl->renv.netconfService; -#endif - - delete impl->renv.nc; - delete impl->renv.sysEnv; - delete impl->renv.topology; - delete impl->renv.sw; - delete impl->renv.multicaster; - delete impl->renv.demarc; - delete impl->renv.prng; - delete impl->renv.log; - - delete impl; + delete (_NodeImpl *)_impl; } -/** - * Execute node in current thread - * - * This does not return until the node shuts down. Shutdown may be caused - * by an internally detected condition such as a new upgrade being - * available or a fatal error, or it may be signaled externally using - * the terminate() method. - * - * @return Reason for termination - */ Node::ReasonForTermination Node::run() throw() { @@ -375,9 +365,9 @@ Node::ReasonForTermination Node::run() // Create the core objects in RuntimeEnvironment: node config, demarcation // point, switch, network topology database, and system environment // watcher. - _r->demarc = new Demarc(_r); _r->multicaster = new Multicaster(); _r->sw = new Switch(_r); + _r->demarc = new Demarc(_r); _r->topology = new Topology(_r,(_r->homePath + ZT_PATH_SEPARATOR_S + "peer.db").c_str()); _r->sysEnv = new SysEnv(_r); try { diff --git a/node/RuntimeEnvironment.hpp b/node/RuntimeEnvironment.hpp index 54cbf7400..c15551d0c 100644 --- a/node/RuntimeEnvironment.hpp +++ b/node/RuntimeEnvironment.hpp @@ -61,6 +61,7 @@ class RuntimeEnvironment { public: RuntimeEnvironment() : + shutdownInProgress(false), log((Logger *)0), prng((CMWC4096 *)0), demarc((Demarc *)0), @@ -82,14 +83,16 @@ public: Identity identity; + volatile bool shutdownInProgress; + // Order matters a bit here. These are constructed in this order // and then deleted in the opposite order on Node exit. Logger *log; // may be null CMWC4096 *prng; - Demarc *demarc; Multicaster *multicaster; Switch *sw; + Demarc *demarc; Topology *topology; SysEnv *sysEnv; NodeConfig *nc;