summaryrefslogtreecommitdiff
path: root/node
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2013-08-09 17:20:40 -0400
committerAdam Ierymenko <adam.ierymenko@gmail.com>2013-08-09 17:20:40 -0400
commit95a23dc7ec9a2ce55cab337b78b662a30ec2b986 (patch)
tree215b13db489ecc9cf9d406f922477cab6ed42aa5 /node
parent7c3a446499d799efe6ff7c299e9a5e2c7c217893 (diff)
downloadinfinitytier-95a23dc7ec9a2ce55cab337b78b662a30ec2b986.tar.gz
infinitytier-95a23dc7ec9a2ce55cab337b78b662a30ec2b986.zip
Fix for another wonderful C++ threading race condition.
Diffstat (limited to 'node')
-rw-r--r--node/EthernetTap.cpp4
-rw-r--r--node/Network.cpp4
-rw-r--r--node/Network.hpp1
3 files changed, 9 insertions, 0 deletions
diff --git a/node/EthernetTap.cpp b/node/EthernetTap.cpp
index 4c300d0b..e6536223 100644
--- a/node/EthernetTap.cpp
+++ b/node/EthernetTap.cpp
@@ -557,6 +557,10 @@ void EthernetTap::threadMain()
char getBuf[4096 + 14];
Buffer<4096> data;
+ // Wait for a moment after startup -- wait for Network to finish
+ // constructing itself.
+ Thread::sleep(500);
+
FD_ZERO(&readfds);
FD_ZERO(&nullfds);
int nfds = (int)std::max(_shutdownSignalPipe[0],_fd) + 1;
diff --git a/node/Network.cpp b/node/Network.cpp
index 9227cd34..3593b732 100644
--- a/node/Network.cpp
+++ b/node/Network.cpp
@@ -139,6 +139,7 @@ SharedPtr<Network> Network::newInstance(const RuntimeEnvironment *renv,uint64_t
// that then causes the Network instance to be deleted before it is finished
// being constructed. C++ edge cases, how I love thee.
SharedPtr<Network> nw(new Network());
+ nw->_ready = false; // disable handling of Ethernet frames during construct
nw->_r = renv;
nw->_rlLimit.bytesPerSecond = ZT_MULTICAST_DEFAULT_BYTES_PER_SECOND;
nw->_rlLimit.maxBalance = ZT_MULTICAST_DEFAULT_RATE_MAX_BALANCE;
@@ -150,6 +151,7 @@ SharedPtr<Network> Network::newInstance(const RuntimeEnvironment *renv,uint64_t
if (nw->controller() == renv->identity.address()) // sanity check, this isn't supported for now
throw std::runtime_error("cannot add a network for which I am the netconf master");
nw->_restoreState();
+ nw->_ready = true; // enable handling of Ethernet frames
nw->requestConfiguration();
return nw;
}
@@ -267,6 +269,8 @@ Network::Status Network::status() const
void Network::_CBhandleTapData(void *arg,const MAC &from,const MAC &to,unsigned int etherType,const Buffer<4096> &data)
{
+ if (!((Network *)arg)->_ready)
+ return;
const RuntimeEnvironment *_r = ((Network *)arg)->_r;
try {
_r->sw->onLocalEthernet(SharedPtr<Network>((Network *)arg),from,to,etherType,data);
diff --git a/node/Network.hpp b/node/Network.hpp
index 312912db..e80d2e65 100644
--- a/node/Network.hpp
+++ b/node/Network.hpp
@@ -472,6 +472,7 @@ private:
uint64_t _id;
volatile uint64_t _lastConfigUpdate;
volatile bool _destroyOnDelete;
+ volatile bool _ready;
Mutex _lock;