mirror of
https://github.com/zerotier/ZeroTierOne.git
synced 2025-02-20 09:46:13 +00:00
CLI debugging, got rid of nasty old Thread class and replaced with newer cleaner portable idiom.
This commit is contained in:
parent
3368330b77
commit
a7c4cbe53a
@ -24,12 +24,16 @@ LIBS=ext/bin/libcrypto/linux-$(ARCH)/libcrypto.a -lm -ldl
|
||||
|
||||
include objects.mk
|
||||
|
||||
all: one launcher
|
||||
all: one cli launcher
|
||||
|
||||
one: $(OBJS)
|
||||
$(CXX) $(CXXFLAGS) -o zerotier-one main.cpp $(OBJS) $(LIBS)
|
||||
$(STRIP) zerotier-one
|
||||
|
||||
cli: $(OBJS)
|
||||
$(CXX) $(CXXFLAGS) -o zerotier-cli cli.cpp $(OBJS) $(LIBS)
|
||||
$(STRIP) zerotier-cli
|
||||
|
||||
selftest: $(OBJS)
|
||||
$(CXX) $(CXXFLAGS) -o zerotier-selftest selftest.cpp $(OBJS) $(LIBS)
|
||||
$(STRIP) zerotier-selftest
|
||||
|
2
cli.cpp
2
cli.cpp
@ -113,7 +113,7 @@ int main(int argc,char **argv)
|
||||
|
||||
lastResultTime = Utils::now();
|
||||
while ((Utils::now() - lastResultTime) < 300)
|
||||
Thread::sleep(50);
|
||||
Thread<void>::sleep(50);
|
||||
|
||||
if (!numResults) {
|
||||
fprintf(stdout,"ERROR: no results received. Is ZeroTier One running?"ZT_EOL_S);
|
||||
|
@ -187,7 +187,7 @@ EthernetTap::EthernetTap(
|
||||
|
||||
TRACE("tap %s created",_dev);
|
||||
|
||||
start();
|
||||
_thread = Thread<EthernetTap>::start(this);
|
||||
}
|
||||
#endif // __LINUX__
|
||||
|
||||
@ -271,14 +271,14 @@ EthernetTap::EthernetTap(
|
||||
|
||||
::pipe(_shutdownSignalPipe);
|
||||
|
||||
start();
|
||||
_thread = Thread<EthernetTap>::start(this);
|
||||
}
|
||||
#endif // __APPLE__
|
||||
|
||||
EthernetTap::~EthernetTap()
|
||||
{
|
||||
::write(_shutdownSignalPipe[1],"\0",1); // causes thread to exit
|
||||
join();
|
||||
Thread<EthernetTap>::join(_thread);
|
||||
::close(_fd);
|
||||
}
|
||||
|
||||
@ -549,7 +549,7 @@ bool EthernetTap::updateMulticastGroups(std::set<MulticastGroup> &groups)
|
||||
}
|
||||
#endif // __APPLE__
|
||||
|
||||
void EthernetTap::main()
|
||||
void EthernetTap::threadMain()
|
||||
throw()
|
||||
{
|
||||
fd_set readfds,nullfds;
|
||||
|
@ -51,7 +51,7 @@ class RuntimeEnvironment;
|
||||
/**
|
||||
* System ethernet tap device
|
||||
*/
|
||||
class EthernetTap : protected Thread
|
||||
class EthernetTap
|
||||
{
|
||||
public:
|
||||
/**
|
||||
@ -79,7 +79,7 @@ public:
|
||||
*
|
||||
* This may block for a few seconds while thread exits.
|
||||
*/
|
||||
virtual ~EthernetTap();
|
||||
~EthernetTap();
|
||||
|
||||
/**
|
||||
* Perform OS dependent actions on network configuration change detection
|
||||
@ -169,8 +169,10 @@ public:
|
||||
*/
|
||||
bool updateMulticastGroups(std::set<MulticastGroup> &groups);
|
||||
|
||||
protected:
|
||||
virtual void main()
|
||||
/**
|
||||
* Thread main method; do not call elsewhere
|
||||
*/
|
||||
void threadMain()
|
||||
throw();
|
||||
|
||||
private:
|
||||
@ -178,6 +180,7 @@ private:
|
||||
const unsigned int _mtu;
|
||||
|
||||
const RuntimeEnvironment *_r;
|
||||
Thread<EthernetTap> _thread;
|
||||
|
||||
std::set<InetAddress> _ips;
|
||||
Mutex _ips_m;
|
||||
|
@ -108,6 +108,8 @@ Network::Network(const RuntimeEnvironment *renv,uint64_t id)
|
||||
_id(id),
|
||||
_lastConfigUpdate(0)
|
||||
{
|
||||
if (controller() == _r->identity.address())
|
||||
throw std::runtime_error("configuration error: cannot add a network for which I am the netconf master");
|
||||
}
|
||||
|
||||
Network::~Network()
|
||||
@ -118,6 +120,7 @@ void Network::setConfiguration(const Network::Config &conf)
|
||||
{
|
||||
Mutex::Lock _l(_lock);
|
||||
if ((conf.networkId() == _id)&&(conf.peerAddress() == _r->identity.address())) { // sanity check
|
||||
TRACE("network %.16llx got netconf:\n%s",(unsigned long long)_id,conf.toString().c_str());
|
||||
_configuration = conf;
|
||||
_myCertificate = conf.certificateOfMembership();
|
||||
_lastConfigUpdate = Utils::now();
|
||||
@ -126,6 +129,11 @@ void Network::setConfiguration(const Network::Config &conf)
|
||||
|
||||
void Network::requestConfiguration()
|
||||
{
|
||||
if (controller() == _r->identity.address()) {
|
||||
LOG("unable to request network configuration for network %.16llx: I am the network master, cannot query self",(unsigned long long)_id);
|
||||
return;
|
||||
}
|
||||
TRACE("requesting netconf for network %.16llx from netconf master %s",(unsigned long long)_id,controller().toString().c_str());
|
||||
Packet outp(controller(),_r->identity.address(),Packet::VERB_NETWORK_CONFIG_REQUEST);
|
||||
outp.append((uint64_t)_id);
|
||||
_r->sw->send(outp,true);
|
||||
|
@ -99,10 +99,10 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Read-only underlying dictionary
|
||||
*/
|
||||
inline const Dictionary &dictionary() const { return *this; }
|
||||
inline std::string toString() const
|
||||
{
|
||||
return Dictionary::toString();
|
||||
}
|
||||
|
||||
inline void setNetworkId(uint64_t id)
|
||||
{
|
||||
@ -208,11 +208,9 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
inline void setNetworkId(uint64_t id)
|
||||
inline std::string toString() const
|
||||
{
|
||||
char buf[32];
|
||||
sprintf(buf,"%.16llx",(unsigned long long)id);
|
||||
(*this)["nwid"] = buf;
|
||||
return Dictionary::toString();
|
||||
}
|
||||
|
||||
inline uint64_t networkId() const
|
||||
@ -221,11 +219,6 @@ public:
|
||||
return strtoull(get("nwid").c_str(),(char **)0,16);
|
||||
}
|
||||
|
||||
inline void setPeerAddress(Address &a)
|
||||
{
|
||||
(*this)["peer"] = a.toString();
|
||||
}
|
||||
|
||||
inline Address peerAddress() const
|
||||
throw(std::invalid_argument)
|
||||
{
|
||||
@ -265,41 +258,6 @@ public:
|
||||
sa.insert(InetAddress(*i));
|
||||
return sa;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set static IPv4 and IPv6 addresses
|
||||
*
|
||||
* This sets the ipv4Static and ipv6Static fields to comma-delimited
|
||||
* lists of assignments. The port field in InetAddress must be the
|
||||
* number of bits in the netmask.
|
||||
*
|
||||
* @param begin Start of container or array of addresses (InetAddress)
|
||||
* @param end End of container or array of addresses (InetAddress)
|
||||
* @tparam I Type of container or array
|
||||
*/
|
||||
template<typename I>
|
||||
inline void setStaticInetAddresses(const I &begin,const I &end)
|
||||
{
|
||||
std::string v4;
|
||||
std::string v6;
|
||||
for(I i(begin);i!=end;++i) {
|
||||
if (i->isV4()) {
|
||||
if (v4.length())
|
||||
v4.push_back(',');
|
||||
v4.append(i->toString());
|
||||
} else if (i->isV6()) {
|
||||
if (v6.length())
|
||||
v6.push_back(',');
|
||||
v6.append(i->toString());
|
||||
}
|
||||
}
|
||||
if (v4.length())
|
||||
(*this)["ipv4Static"] = v4;
|
||||
else erase("ipv4Static");
|
||||
if (v6.length())
|
||||
(*this)["ipv6Static"] = v6;
|
||||
else erase("ipv6Static");
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
|
@ -426,7 +426,7 @@ Node::ReasonForTermination Node::run()
|
||||
if (lastDelayDelta >= ZT_SLEEP_WAKE_DETECTION_THRESHOLD) {
|
||||
resynchronize = true;
|
||||
LOG("probable suspend/resume detected, pausing a moment for things to settle...");
|
||||
Thread::sleep(ZT_SLEEP_WAKE_SETTLE_TIME);
|
||||
Thread<Node>::sleep(ZT_SLEEP_WAKE_SETTLE_TIME);
|
||||
}
|
||||
|
||||
// Periodically check our network environment, sending pings out to all
|
||||
|
@ -243,8 +243,10 @@ void NodeConfig::_CBcontrolPacketHandler(UdpSocket *sock,void *arg,const InetAdd
|
||||
for(std::vector< Buffer<ZT_NODECONFIG_MAX_PACKET_SIZE> >::iterator p(resultPackets.begin());p!=resultPackets.end();++p)
|
||||
sock->send(remoteAddr,p->data(),p->size(),-1);
|
||||
}
|
||||
} catch (std::exception &exc) {
|
||||
TRACE("exception handling control bus packet from %s: %s",remoteAddr.toString().c_str(),exc.what());
|
||||
} catch ( ... ) {
|
||||
TRACE("exception handling control bus packet from %s",remoteAddr.toString().c_str());
|
||||
TRACE("exception handling control bus packet from %s: (unknown)",remoteAddr.toString().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,7 @@ Service::Service(const RuntimeEnvironment *renv,const char *name,const char *pat
|
||||
_childStderr(0),
|
||||
_run(true)
|
||||
{
|
||||
start();
|
||||
_thread = Thread<Service>::start(this);
|
||||
}
|
||||
|
||||
Service::~Service()
|
||||
@ -77,14 +77,14 @@ Service::~Service()
|
||||
pid = 0;
|
||||
break;
|
||||
}
|
||||
Thread::sleep(100);
|
||||
Thread<Service>::sleep(100);
|
||||
}
|
||||
if (pid > 0) {
|
||||
::kill(pid,SIGKILL);
|
||||
waitpid(pid,&st,0);
|
||||
}
|
||||
}
|
||||
join();
|
||||
Thread<Service>::join(_thread);
|
||||
}
|
||||
|
||||
bool Service::send(const Dictionary &msg)
|
||||
@ -107,7 +107,7 @@ bool Service::send(const Dictionary &msg)
|
||||
return true;
|
||||
}
|
||||
|
||||
void Service::main()
|
||||
void Service::threadMain()
|
||||
throw()
|
||||
{
|
||||
char buf[131072];
|
||||
@ -136,7 +136,7 @@ void Service::main()
|
||||
close(in[0]);
|
||||
close(out[1]);
|
||||
close(err[1]);
|
||||
Thread::sleep(500); // give child time to start
|
||||
Thread<Service>::sleep(500); // give child time to start
|
||||
_childStdin = in[1];
|
||||
_childStdout = out[0];
|
||||
_childStderr = err[0];
|
||||
@ -168,7 +168,7 @@ void Service::main()
|
||||
|
||||
LOG("service %s exited with exit code: %d, delaying 1s to attempt relaunch",_name.c_str(),st);
|
||||
|
||||
Thread::sleep(1000); // wait to relaunch
|
||||
Thread<Service>::sleep(1000); // wait to relaunch
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ class RuntimeEnvironment;
|
||||
* logged via the standard Logger instance. If the subprocess dies, an
|
||||
* attempt is made to restart it every second.
|
||||
*/
|
||||
class Service : protected Thread
|
||||
class Service
|
||||
{
|
||||
public:
|
||||
/**
|
||||
@ -78,7 +78,7 @@ public:
|
||||
void (*handler)(void *,Service &,const Dictionary &),
|
||||
void *arg);
|
||||
|
||||
virtual ~Service();
|
||||
~Service();
|
||||
|
||||
/**
|
||||
* Send a message to service subprocess
|
||||
@ -106,12 +106,15 @@ public:
|
||||
return (_pid > 0);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void main()
|
||||
/**
|
||||
* Thread main method; do not call elsewhere
|
||||
*/
|
||||
void threadMain()
|
||||
throw();
|
||||
|
||||
private:
|
||||
const RuntimeEnvironment *_r;
|
||||
Thread<Service> _thread;
|
||||
std::string _path;
|
||||
std::string _name;
|
||||
void *_arg;
|
||||
|
182
node/Thread.cpp
182
node/Thread.cpp
@ -1,182 +0,0 @@
|
||||
/*
|
||||
* ZeroTier One - Global Peer to Peer Ethernet
|
||||
* Copyright (C) 2012-2013 ZeroTier Networks LLC
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* --
|
||||
*
|
||||
* ZeroTier may be used and distributed under the terms of the GPLv3, which
|
||||
* are available at: http://www.gnu.org/licenses/gpl-3.0.html
|
||||
*
|
||||
* If you would like to embed ZeroTier into a commercial application or
|
||||
* redistribute it in a modified binary form, please contact ZeroTier Networks
|
||||
* LLC. Start here: http://www.zerotier.com/
|
||||
*/
|
||||
|
||||
#include "Thread.hpp"
|
||||
|
||||
#if defined(__APPLE__) || defined(__linux__) || defined(linux) || defined(__LINUX__) || defined(__linux)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <stdexcept>
|
||||
|
||||
extern "C" {
|
||||
static void *__m_thread_main(void *ptr)
|
||||
{
|
||||
((ZeroTier::Thread *)ptr)->__intl_run();
|
||||
return (void *)0;
|
||||
}
|
||||
}
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
Thread::Thread() :
|
||||
_impl(malloc(sizeof(pthread_t))),
|
||||
_running()
|
||||
{
|
||||
memset(_impl,0,sizeof(pthread_t));
|
||||
}
|
||||
|
||||
Thread::~Thread()
|
||||
{
|
||||
free(_impl);
|
||||
}
|
||||
|
||||
void Thread::start()
|
||||
{
|
||||
if (!*_running) {
|
||||
++_running;
|
||||
pthread_create((pthread_t *)_impl,(const pthread_attr_t *)0,&__m_thread_main,(void *)this);
|
||||
}
|
||||
}
|
||||
|
||||
void Thread::join()
|
||||
{
|
||||
void *tmp;
|
||||
if (*_running)
|
||||
pthread_join(*((pthread_t *)_impl),&tmp);
|
||||
}
|
||||
|
||||
void Thread::sleep(unsigned long ms)
|
||||
{
|
||||
usleep(ms * 1000);
|
||||
}
|
||||
|
||||
void Thread::__intl_run()
|
||||
{
|
||||
for(;;) {
|
||||
_notInit = false;
|
||||
this->main();
|
||||
if (_notInit) // UGLY ASS HACK: see main()
|
||||
usleep(50);
|
||||
else break;
|
||||
}
|
||||
--_running;
|
||||
}
|
||||
|
||||
void Thread::main()
|
||||
throw()
|
||||
{
|
||||
_notInit = true; // UGLY ASS HACK: retry if subclass has not defined virtual function pointer yet
|
||||
}
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <Windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
DWORD WINAPI __m_thread_main(LPVOID lpParam)
|
||||
{
|
||||
((ZeroTier::Thread *)lpParam)->__intl_run();
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct __m_thread_info
|
||||
{
|
||||
HANDLE threadHandle;
|
||||
DWORD threadId;
|
||||
bool started;
|
||||
};
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
Thread::Thread() :
|
||||
_impl(malloc(sizeof(__m_thread_info))),
|
||||
_running()
|
||||
{
|
||||
memset(_impl,0,sizeof(__m_thread_info));
|
||||
}
|
||||
|
||||
Thread::~Thread()
|
||||
{
|
||||
if (((__m_thread_info *)_impl)->started)
|
||||
CloseHandle(((__m_thread_info *)_impl)->threadHandle);
|
||||
free(_impl);
|
||||
}
|
||||
|
||||
void Thread::start()
|
||||
{
|
||||
if (!*_running) {
|
||||
++_running;
|
||||
if ((((__m_thread_info *)_impl)->threadHandle = CreateThread(NULL,0,__m_thread_main,this,0,&(((__m_thread_info *)_impl)->threadId))) != NULL) {
|
||||
((__m_thread_info *)_impl)->started = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Thread::join()
|
||||
{
|
||||
if (*_running)
|
||||
WaitForSingleObject(((__m_thread_info *)_impl)->threadHandle,INFINITE);
|
||||
}
|
||||
|
||||
void Thread::__intl_run()
|
||||
{
|
||||
for(;;) {
|
||||
_notInit = false;
|
||||
this->main();
|
||||
if (_notInit)
|
||||
Thread::sleep(50);
|
||||
else break;
|
||||
}
|
||||
--_running;
|
||||
}
|
||||
|
||||
void Thread::main()
|
||||
throw()
|
||||
{
|
||||
_notInit = true; // HACK: retry if subclass has not defined virtual function pointer yet
|
||||
}
|
||||
|
||||
struct _Thread_RunInBackgroundData
|
||||
{
|
||||
void (*func)(void *);
|
||||
void *ptr;
|
||||
HANDLE threadHandle;
|
||||
DWORD threadId;
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
#endif
|
106
node/Thread.hpp
106
node/Thread.hpp
@ -28,62 +28,104 @@
|
||||
#ifndef _ZT_THREAD_HPP
|
||||
#define _ZT_THREAD_HPP
|
||||
|
||||
#include "NonCopyable.hpp"
|
||||
#include <stdexcept>
|
||||
|
||||
#include "Constants.hpp"
|
||||
#include "AtomicCounter.hpp"
|
||||
|
||||
#ifdef __WINDOWS__
|
||||
|
||||
todo need windows;
|
||||
|
||||
#else
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace ZeroTier {
|
||||
|
||||
template<typename C>
|
||||
static void *___zt_threadMain(void *instance)
|
||||
{
|
||||
try {
|
||||
((C *)instance)->threadMain();
|
||||
} catch ( ... ) {}
|
||||
return (void *)0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for OS-dependent thread functions like pthread_create, etc.
|
||||
* A thread of a given class type
|
||||
*
|
||||
* @tparam C Class using Thread
|
||||
*/
|
||||
class Thread : NonCopyable
|
||||
template<typename C>
|
||||
class Thread
|
||||
{
|
||||
public:
|
||||
Thread();
|
||||
virtual ~Thread();
|
||||
Thread()
|
||||
throw()
|
||||
{
|
||||
memset(&_tid,0,sizeof(_tid));
|
||||
}
|
||||
|
||||
Thread(const Thread &t)
|
||||
throw()
|
||||
{
|
||||
memcpy(&_tid,&(t._tid),sizeof(_tid));
|
||||
}
|
||||
|
||||
inline Thread &operator=(const Thread &t)
|
||||
throw()
|
||||
{
|
||||
memcpy(&_tid,&(t._tid),sizeof(_tid));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start thread -- can only be called once
|
||||
*/
|
||||
void start();
|
||||
|
||||
/**
|
||||
* Wait for thread to terminate
|
||||
* Start a new thread
|
||||
*
|
||||
* More than one thread should not simultaneously use join().
|
||||
* @param instance Instance whose threadMain() method gets called by new thread
|
||||
* @return Thread identifier
|
||||
* @throws std::runtime_error Unable to create thread
|
||||
*/
|
||||
void join();
|
||||
static inline Thread start(C *instance)
|
||||
throw(std::runtime_error)
|
||||
{
|
||||
Thread t;
|
||||
if (pthread_create(&t._tid,(const pthread_attr_t *)0,&___zt_threadMain<C>,instance))
|
||||
throw std::runtime_error("pthread_create() failed, unable to create thread");
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if thread is running
|
||||
* Join to a thread, waiting for it to terminate
|
||||
*
|
||||
* @param t Thread to join
|
||||
*/
|
||||
inline bool running() const { return (*_running > 0); }
|
||||
|
||||
/**
|
||||
* Internal bounce method; do not call or override
|
||||
*/
|
||||
void __intl_run();
|
||||
static inline void join(const Thread &t)
|
||||
{
|
||||
pthread_join(t._tid,(void **)0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sleep the current thread
|
||||
*
|
||||
* @param ms Milliseconds to sleep
|
||||
* @param ms Number of milliseconds to sleep
|
||||
*/
|
||||
static void sleep(unsigned long ms);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Override to set a thread main function
|
||||
*/
|
||||
virtual void main()
|
||||
throw();
|
||||
static inline void sleep(unsigned long ms)
|
||||
{
|
||||
usleep(ms * 1000);
|
||||
}
|
||||
|
||||
private:
|
||||
void *_impl;
|
||||
AtomicCounter _running;
|
||||
volatile bool _notInit;
|
||||
pthread_t _tid;
|
||||
};
|
||||
|
||||
} // namespace ZeroTier
|
||||
|
||||
#endif // __WINDOWS__ / !__WINDOWS__
|
||||
|
||||
#endif
|
||||
|
@ -38,7 +38,6 @@ namespace ZeroTier {
|
||||
|
||||
Topology::Topology(const RuntimeEnvironment *renv,const char *dbpath)
|
||||
throw(std::runtime_error) :
|
||||
Thread(),
|
||||
_r(renv),
|
||||
_amSupernode(false)
|
||||
{
|
||||
@ -55,7 +54,7 @@ Topology::Topology(const RuntimeEnvironment *renv,const char *dbpath)
|
||||
|
||||
Utils::lockDownFile(dbpath,false); // node.db caches secrets
|
||||
|
||||
start();
|
||||
_thread = Thread<Topology>::start(this);
|
||||
}
|
||||
|
||||
Topology::~Topology()
|
||||
@ -68,10 +67,7 @@ Topology::~Topology()
|
||||
_peerDeepVerifyJobs.back().type = _PeerDeepVerifyJob::EXIT_THREAD;
|
||||
}
|
||||
_peerDeepVerifyJobs_c.signal();
|
||||
|
||||
while (running())
|
||||
Thread::sleep(10); // wait for thread to terminate without join()
|
||||
|
||||
Thread<Topology>::join(_thread);
|
||||
KISSDB_close(&_dbm);
|
||||
}
|
||||
|
||||
@ -223,7 +219,7 @@ void Topology::clean()
|
||||
_peerDeepVerifyJobs_c.signal();
|
||||
}
|
||||
|
||||
void Topology::main()
|
||||
void Topology::threadMain()
|
||||
throw()
|
||||
{
|
||||
for(;;) {
|
||||
|
@ -55,7 +55,7 @@ class RuntimeEnvironment;
|
||||
/**
|
||||
* Database of network topology
|
||||
*/
|
||||
class Topology : protected Thread
|
||||
class Topology
|
||||
{
|
||||
public:
|
||||
/**
|
||||
@ -74,7 +74,7 @@ public:
|
||||
Topology(const RuntimeEnvironment *renv,const char *dbpath)
|
||||
throw(std::runtime_error);
|
||||
|
||||
virtual ~Topology();
|
||||
~Topology();
|
||||
|
||||
/**
|
||||
* Set up supernodes for this network
|
||||
@ -276,8 +276,10 @@ public:
|
||||
std::vector< SharedPtr<Peer> > &_v;
|
||||
};
|
||||
|
||||
protected:
|
||||
virtual void main()
|
||||
/**
|
||||
* Thread main method; do not call elsewhere
|
||||
*/
|
||||
void threadMain()
|
||||
throw();
|
||||
|
||||
private:
|
||||
@ -297,6 +299,7 @@ private:
|
||||
};
|
||||
|
||||
const RuntimeEnvironment *const _r;
|
||||
Thread<Topology> _thread;
|
||||
|
||||
std::map< Address,SharedPtr<Peer> > _activePeers;
|
||||
Mutex _activePeers_m;
|
||||
|
@ -55,7 +55,6 @@ UdpSocket::UdpSocket(
|
||||
void (*packetHandler)(UdpSocket *,void *,const InetAddress &,const void *,unsigned int),
|
||||
void *arg)
|
||||
throw(std::runtime_error) :
|
||||
Thread(),
|
||||
_packetHandler(packetHandler),
|
||||
_arg(arg),
|
||||
_localPort(localPort),
|
||||
@ -121,7 +120,7 @@ UdpSocket::UdpSocket(
|
||||
}
|
||||
}
|
||||
|
||||
start();
|
||||
_thread = Thread<UdpSocket>::start(this);
|
||||
}
|
||||
|
||||
UdpSocket::~UdpSocket()
|
||||
@ -146,7 +145,7 @@ bool UdpSocket::send(const InetAddress &to,const void *data,unsigned int len,int
|
||||
}
|
||||
}
|
||||
|
||||
void UdpSocket::main()
|
||||
void UdpSocket::threadMain()
|
||||
throw()
|
||||
{
|
||||
char buf[32768];
|
||||
|
@ -40,7 +40,7 @@ namespace ZeroTier {
|
||||
*
|
||||
* The socket listens in a background thread and sends packets to Switch.
|
||||
*/
|
||||
class UdpSocket : protected Thread
|
||||
class UdpSocket
|
||||
{
|
||||
public:
|
||||
/**
|
||||
@ -61,7 +61,7 @@ public:
|
||||
void *arg)
|
||||
throw(std::runtime_error);
|
||||
|
||||
virtual ~UdpSocket();
|
||||
~UdpSocket();
|
||||
|
||||
/**
|
||||
* @return Locally bound port
|
||||
@ -87,11 +87,14 @@ public:
|
||||
bool send(const InetAddress &to,const void *data,unsigned int len,int hopLimit)
|
||||
throw();
|
||||
|
||||
protected:
|
||||
virtual void main()
|
||||
/**
|
||||
* Thread main method; do not call elsewhere
|
||||
*/
|
||||
void threadMain()
|
||||
throw();
|
||||
|
||||
private:
|
||||
Thread<UdpSocket> _thread;
|
||||
void (*_packetHandler)(UdpSocket *,void *,const InetAddress &,const void *,unsigned int);
|
||||
void *_arg;
|
||||
int _localPort;
|
||||
|
@ -21,7 +21,6 @@ OBJS=\
|
||||
node/Service.o \
|
||||
node/Switch.o \
|
||||
node/SysEnv.o \
|
||||
node/Thread.o \
|
||||
node/Topology.o \
|
||||
node/UdpSocket.o \
|
||||
node/Utils.o
|
||||
|
Loading…
x
Reference in New Issue
Block a user