summaryrefslogtreecommitdiff
path: root/service/One.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'service/One.cpp')
-rw-r--r--service/One.cpp152
1 files changed, 74 insertions, 78 deletions
diff --git a/service/One.cpp b/service/One.cpp
index 2ebfd285..20be7006 100644
--- a/service/One.cpp
+++ b/service/One.cpp
@@ -39,7 +39,6 @@
#include "../node/InetAddress.hpp"
#include "../osdep/Phy.hpp"
-#include "../osdep/Thread.hpp"
#include "../osdep/OSUtils.hpp"
#include "One.hpp"
@@ -109,22 +108,73 @@ public:
in6.sin6_port = in4.sin_port;
_v6UdpSocket = _phy.udpBind((const struct sockaddr *)&in6,this,131072);
_v6TcpListenSocket = _phy.tcpListen((const struct sockaddr *)&in6,this);
-
- _thread = Thread::start(this);
}
virtual ~OneImpl()
{
- if (reasonForTermination() == ONE_STILL_RUNNING) {
- terminate();
- waitForTermination();
- }
_phy.close(_v4UdpSocket);
_phy.close(_v6UdpSocket);
_phy.close(_v4TcpListenSocket);
_phy.close(_v6TcpListenSocket);
}
+ virtual ReasonForTermination run()
+ {
+ try {
+ _node = new Node(
+ OSUtils::now(),
+ this,
+ SnodeDataStoreGetFunction,
+ SnodeDataStorePutFunction,
+ SnodeWirePacketSendFunction,
+ SnodeVirtualNetworkFrameFunction,
+ SnodeVirtualNetworkConfigFunction,
+ SnodeEventCallback,
+ ((_overrideRootTopology.length() > 0) ? _overrideRootTopology.c_str() : (const char *)0));
+
+ if (_master)
+ _node->setNetconfMaster((void *)_master);
+
+ _nextBackgroundTaskDeadline = 0;
+ for(;;) {
+ _run_m.lock();
+ if (!_run) {
+ _run_m.unlock();
+ _termReason_m.lock();
+ _termReason = ONE_NORMAL_TERMINATION;
+ _termReason_m.unlock();
+ break;
+ } else _run_m.unlock();
+
+ uint64_t dl = _nextBackgroundTaskDeadline;
+ uint64_t now = OSUtils::now();
+
+ if (dl <= now) {
+ _node->processBackgroundTasks(now,const_cast<uint64_t *>(&_nextBackgroundTaskDeadline));
+ dl = _nextBackgroundTaskDeadline;
+ now = OSUtils::now();
+ }
+
+ const unsigned long delay = (dl > now) ? (unsigned long)(dl - now) : 100;
+ printf("polling: %lums timeout\n",delay);
+ _phy.poll(delay);
+ }
+ } catch (std::exception &exc) {
+ Mutex::Lock _l(_termReason_m);
+ _termReason = ONE_UNRECOVERABLE_ERROR;
+ _fatalErrorMessage = exc.what();
+ } catch ( ... ) {
+ Mutex::Lock _l(_termReason_m);
+ _termReason = ONE_UNRECOVERABLE_ERROR;
+ _fatalErrorMessage = "unexpected exception in main thread";
+ }
+
+ delete _node;
+ _node = (Node *)0;
+
+ return _termReason;
+ }
+
virtual ReasonForTermination reasonForTermination() const
{
Mutex::Lock _l(_termReason_m);
@@ -137,12 +187,6 @@ public:
return _fatalErrorMessage;
}
- virtual void waitForTermination()
- {
- if (reasonForTermination() == ONE_STILL_RUNNING)
- Thread::join(_thread);
- }
-
virtual void terminate()
{
_run_m.lock();
@@ -155,21 +199,23 @@ public:
inline void phyOnDatagramFunction(PhySocket *sock,const struct sockaddr *from,void *data,unsigned long len)
{
- ZT1_ResultCode rc = _node->processWirePacket(
- OSUtils::now(),
- (const struct sockaddr_storage *)from, // Phy<> uses sockaddr_storage, so it'll always be that big
- 0,
- data,
- len,
- const_cast<uint64_t *>(&_nextBackgroundTaskDeadline));
- if (ZT1_ResultCode_isFatal(rc)) {
- char tmp[256];
- Utils::snprintf(tmp,sizeof(tmp),"fatal error code from processWirePacket(%d)",(int)rc);
- Mutex::Lock _l(_termReason_m);
- _termReason = ONE_UNRECOVERABLE_ERROR;
- _fatalErrorMessage = tmp;
- this->terminate();
- }
+ try {
+ ZT1_ResultCode rc = _node->processWirePacket(
+ OSUtils::now(),
+ (const struct sockaddr_storage *)from, // Phy<> uses sockaddr_storage, so it'll always be that big
+ 0,
+ data,
+ len,
+ const_cast<uint64_t *>(&_nextBackgroundTaskDeadline));
+ if (ZT1_ResultCode_isFatal(rc)) {
+ char tmp[256];
+ Utils::snprintf(tmp,sizeof(tmp),"fatal error code from processWirePacket(%d)",(int)rc);
+ Mutex::Lock _l(_termReason_m);
+ _termReason = ONE_UNRECOVERABLE_ERROR;
+ _fatalErrorMessage = tmp;
+ this->terminate();
+ }
+ } catch ( ... ) {}
}
inline void phyOnTcpConnectFunction(PhySocket *sock,bool success)
@@ -309,55 +355,6 @@ public:
fflush(stderr);
}
- void threadMain()
- throw()
- {
- _nextBackgroundTaskDeadline = 0;
- try {
- _node = new Node(
- OSUtils::now(),
- this,
- SnodeDataStoreGetFunction,
- SnodeDataStorePutFunction,
- SnodeWirePacketSendFunction,
- SnodeVirtualNetworkFrameFunction,
- SnodeVirtualNetworkConfigFunction,
- SnodeEventCallback,
- ((_overrideRootTopology.length() > 0) ? _overrideRootTopology.c_str() : (const char *)0));
-
- if (_master)
- _node->setNetconfMaster((void *)_master);
-
- for(;;) {
- _run_m.lock();
- if (!_run) {
- _run_m.unlock();
- break;
- } else _run_m.unlock();
-
- uint64_t dl = _nextBackgroundTaskDeadline;
- uint64_t now = OSUtils::now();
-
- if (dl <= now) {
- _node->processBackgroundTasks(now,const_cast<uint64_t *>(&_nextBackgroundTaskDeadline));
- dl = _nextBackgroundTaskDeadline;
- now = OSUtils::now();
- }
-
- _phy.poll((dl > now) ? (unsigned long)(dl - now) : 100);
- }
- } catch (std::exception &exc) {
- Mutex::Lock _l(_termReason_m);
- _termReason = ONE_UNRECOVERABLE_ERROR;
- _fatalErrorMessage = exc.what();
- } catch ( ... ) {
- Mutex::Lock _l(_termReason_m);
- _termReason = ONE_UNRECOVERABLE_ERROR;
- _fatalErrorMessage = "unexpected exception in main thread";
- }
- delete _node;
- }
-
private:
const std::string _homePath;
SimpleFunctionPhy _phy;
@@ -368,7 +365,6 @@ private:
PhySocket *_v6UdpSocket;
PhySocket *_v4TcpListenSocket;
PhySocket *_v6TcpListenSocket;
- Thread _thread;
volatile uint64_t _nextBackgroundTaskDeadline;
ReasonForTermination _termReason;