summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2015-04-10 11:40:45 -0700
committerAdam Ierymenko <adam.ierymenko@gmail.com>2015-04-10 11:40:45 -0700
commit9e651b39e416171812d0dd3835a0cb9958aed264 (patch)
tree96c13a53faee912191467fed2d033458aae6f85b /service
parent08a11a6f32329d26e5e85b7f66e66591d2fd1069 (diff)
downloadinfinitytier-9e651b39e416171812d0dd3835a0cb9958aed264.tar.gz
infinitytier-9e651b39e416171812d0dd3835a0cb9958aed264.zip
Add some TRACE around pinging (for now), and refactor service/One to just run in the foreground as some platforms may not require threads at all.
Diffstat (limited to 'service')
-rw-r--r--service/One.cpp152
-rw-r--r--service/One.hpp26
2 files changed, 89 insertions, 89 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;
diff --git a/service/One.hpp b/service/One.hpp
index 26071656..1a33dc72 100644
--- a/service/One.hpp
+++ b/service/One.hpp
@@ -75,7 +75,10 @@ public:
static std::string platformDefaultHomePath();
/**
- * Create and start a new instance of the service
+ * Create a new instance of the service
+ *
+ * Once created, you must call the run() method to actually start
+ * processing.
*
* @param hp Home path
* @param port TCP and UDP port for packets and HTTP control
@@ -88,10 +91,18 @@ public:
NetworkConfigMaster *master = (NetworkConfigMaster *)0,
const char *overrideRootTopology = (const char *)0);
+ virtual ~One();
+
/**
- * Deletion will block until service stops if it's still running
+ * Execute the service main I/O loop until terminated
+ *
+ * The terminate() method may be called from a signal handler or another
+ * thread to terminate execution. Otherwise this will not return unless
+ * another condition terminates execution such as a fatal error.
+ *
+ * @param
*/
- virtual ~One();
+ virtual ReasonForTermination run() = 0;
/**
* @return Reason for terminating or ONE_STILL_RUNNING if running
@@ -104,14 +115,7 @@ public:
virtual std::string fatalErrorMessage() const = 0;
/**
- * Block until service terminates
- */
- virtual void waitForTermination() = 0;
-
- /**
- * Terminate background service
- *
- * Actual shutdown might take a few seconds.
+ * Terminate background service (can be called from other threads)
*/
virtual void terminate() = 0;