Browse Source

Fix for another wonderful C++ threading race condition.

Adam Ierymenko 12 years ago
parent
commit
95a23dc7ec
4 changed files with 13 additions and 4 deletions
  1. 4 4
      Makefile.linux
  2. 4 0
      node/EthernetTap.cpp
  3. 4 0
      node/Network.cpp
  4. 1 0
      node/Network.hpp

+ 4 - 4
Makefile.linux

@@ -6,12 +6,12 @@ ARCH=$(shell uname -m)
 DEFS=-DZT_ARCH="$(ARCH)" -DZT_OSNAME="linux" -DZT_TRACE
 
 # Uncomment for a release optimized build
-CFLAGS=-Wall -O3 -fno-unroll-loops -fstack-protector -pthread $(INCLUDES) -DNDEBUG $(DEFS)
-STRIP=strip --strip-all
+#CFLAGS=-Wall -O3 -fno-unroll-loops -fstack-protector -pthread $(INCLUDES) -DNDEBUG $(DEFS)
+#STRIP=strip --strip-all
 
 # Uncomment for a debug build
-#CFLAGS=-Wall -g -pthread $(INCLUDES) -DZT_TRACE -DZT_LOG_STDOUT $(DEFS)
-#STRIP=echo
+CFLAGS=-Wall -g -pthread $(INCLUDES) -DZT_TRACE $(DEFS)
+STRIP=echo
 
 CXXFLAGS=$(CFLAGS) -fno-rtti
 

+ 4 - 0
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;

+ 4 - 0
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);

+ 1 - 0
node/Network.hpp

@@ -472,6 +472,7 @@ private:
 	uint64_t _id;
 	volatile uint64_t _lastConfigUpdate;
 	volatile bool _destroyOnDelete;
+	volatile bool _ready;
 
 	Mutex _lock;