From 934a575a7447bb34360e9f9f27dace971f811ce5 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Mon, 27 Oct 2014 18:23:10 -0700 Subject: [PATCH] Testnet seems to work a bit better now... --- node/Node.cpp | 1 - testnet.cpp | 8 ++-- testnet/{Condition.hpp => Semaphore.hpp} | 60 ++++++++++++------------ testnet/SimNetSocketManager.hpp | 4 +- testnet/TestEthernetTap.hpp | 4 +- 5 files changed, 38 insertions(+), 39 deletions(-) rename testnet/{Condition.hpp => Semaphore.hpp} (71%) diff --git a/node/Node.cpp b/node/Node.cpp index 07f6637b7..7ca435aea 100644 --- a/node/Node.cpp +++ b/node/Node.cpp @@ -100,7 +100,6 @@ struct _NodeImpl LOG("terminating: %s",reasonForTerminationStr.c_str()); renv.shutdownInProgress = true; - Thread::sleep(500); running = false; diff --git a/testnet.cpp b/testnet.cpp index cab3248ed..be4744043 100644 --- a/testnet.cpp +++ b/testnet.cpp @@ -510,7 +510,7 @@ static void doUnicast(const std::vector &cmd) for(unsigned int i=0;i > sentPairs; for(std::vector
::iterator s(senders.begin());s!=senders.end();++s) { for(std::vector
::iterator r(receivers.begin());r!=receivers.end();++r) { if (*s == *r) @@ -526,7 +526,7 @@ static void doUnicast(const std::vector &cmd) pkt.i[1] = Utils::now(); stap->injectPacketFromHost(stap->mac(),rtap->mac(),0xdead,pkt.data,frameLen); printf("%s -> %s etherType 0xdead network %.16llx length %u"ZT_EOL_S,s->toString().c_str(),r->toString().c_str(),nwid,frameLen); - ++sentCount; + sentPairs.insert(std::pair(*s,*r)); } else if (stap) { printf("%s -> !%s (receiver not a member of %.16llx)"ZT_EOL_S,s->toString().c_str(),r->toString().c_str(),nwid); } else if (rtap) { @@ -561,13 +561,13 @@ static void doUnicast(const std::vector &cmd) } } Thread::sleep(250); - } while ((receivedPairs.size() < sentCount)&&(Utils::now() < toutend)); + } while ((receivedPairs.size() < sentPairs.size())&&(Utils::now() < toutend)); for(std::vector
::iterator s(senders.begin());s!=senders.end();++s) { for(std::vector
::iterator r(receivers.begin());r!=receivers.end();++r) { if (*s == *r) continue; - if (!receivedPairs.count(std::pair(*s,*r))) { + if ((sentPairs.count(std::pair(*s,*r)))&&(!receivedPairs.count(std::pair(*s,*r)))) { printf("%s <- %s was never received (timed out)"ZT_EOL_S,r->toString().c_str(),s->toString().c_str()); } } diff --git a/testnet/Condition.hpp b/testnet/Semaphore.hpp similarity index 71% rename from testnet/Condition.hpp rename to testnet/Semaphore.hpp index 3794ee60d..d1c0d4169 100644 --- a/testnet/Condition.hpp +++ b/testnet/Semaphore.hpp @@ -25,8 +25,8 @@ * LLC. Start here: http://www.zerotier.com/ */ -#ifndef ZT_CONDITION_HPP -#define ZT_CONDITION_HPP +#ifndef ZT_SEMAPHORE_HPP +#define ZT_SEMAPHORE_HPP #include "../node/Constants.hpp" #include "../node/NonCopyable.hpp" @@ -38,30 +38,16 @@ namespace ZeroTier { -class Condition : NonCopyable +class Semaphore : NonCopyable { public: - Condition() + Semaphore() throw() { _sem = CreateSemaphore(NULL,0,0x7fffffff,NULL); } + ~Semaphore() { CloseHandle(_sem); } + + inline void wait(unsigned long ms = 0) const throw() { - _sem = CreateSemaphore(NULL,0,1,NULL); - } - - ~Condition() - { - CloseHandle(_sem); - } - - inline void wait() const - throw() - { - WaitForSingleObject(_sem,INFINITE); - } - - inline void wait(unsigned long ms) const - throw() - { - if (ms) + if (ms > 0) WaitForSingleObject(_sem,(DWORD)ms); else WaitForSingleObject(_sem,INFINITE); } @@ -88,51 +74,65 @@ private: namespace ZeroTier { -class Condition : NonCopyable +// This isn't quite a perfect semaphore, but the way we use it it's fine... we +// just want this to signal when queues are ready. +class Semaphore : NonCopyable { public: - Condition() + Semaphore() throw() { pthread_mutex_init(&_mh,(const pthread_mutexattr_t *)0); pthread_cond_init(&_cond,(const pthread_condattr_t *)0); + _cnt = 0; } - ~Condition() + ~Semaphore() { pthread_cond_destroy(&_cond); pthread_mutex_destroy(&_mh); } - inline void wait() const + inline void wait() throw() { pthread_mutex_lock(const_cast (&_mh)); - pthread_cond_wait(const_cast (&_cond),const_cast (&_mh)); + if (_cnt <= 0) + pthread_cond_wait(const_cast (&_cond),const_cast (&_mh)); + if (_cnt > 0) + --_cnt; pthread_mutex_unlock(const_cast (&_mh)); } - inline void wait(unsigned long ms) const + inline void wait(unsigned long ms) throw() { uint64_t when = Utils::now() + (uint64_t)ms; struct timespec ts; ts.tv_sec = (unsigned long)(when / 1000); ts.tv_nsec = (unsigned long)(when % 1000) * 1000000; + pthread_mutex_lock(const_cast (&_mh)); - pthread_cond_timedwait(const_cast (&_cond),const_cast (&_mh),&ts); + if (_cnt <= 0) + pthread_cond_timedwait(const_cast (&_cond),const_cast (&_mh),&ts); + if (_cnt > 0) + --_cnt; pthread_mutex_unlock(const_cast (&_mh)); } - inline void signal() const + inline void signal() throw() { + pthread_mutex_lock(const_cast (&_mh)); + ++_cnt; + pthread_mutex_unlock(const_cast (&_mh)); pthread_cond_signal(const_cast (&_cond)); } private: pthread_cond_t _cond; pthread_mutex_t _mh; + volatile int _cnt; }; } // namespace ZeroTier diff --git a/testnet/SimNetSocketManager.hpp b/testnet/SimNetSocketManager.hpp index 1dde7fe8e..df5870721 100644 --- a/testnet/SimNetSocketManager.hpp +++ b/testnet/SimNetSocketManager.hpp @@ -35,7 +35,7 @@ #include "../node/Constants.hpp" #include "../node/SocketManager.hpp" #include "../node/Mutex.hpp" -#include "Condition.hpp" +#include "Semaphore.hpp" namespace ZeroTier { @@ -120,7 +120,7 @@ private: std::map< InetAddress,TransferStats > _stats; Mutex _stats_m; - Condition _waitCond; + Semaphore _waitCond; }; } // namespace ZeroTier diff --git a/testnet/TestEthernetTap.hpp b/testnet/TestEthernetTap.hpp index babd35ad4..3b1782e3d 100644 --- a/testnet/TestEthernetTap.hpp +++ b/testnet/TestEthernetTap.hpp @@ -40,7 +40,7 @@ #include "../node/SharedPtr.hpp" #include "../node/Thread.hpp" #include "../node/Mutex.hpp" -#include "Condition.hpp" +#include "Semaphore.hpp" namespace ZeroTier { @@ -129,7 +129,7 @@ private: std::vector< TestFrame > _pq; Mutex _pq_m; - Condition _pq_c; + Semaphore _pq_c; std::vector< TestFrame > _gq; Mutex _gq_m;