summaryrefslogtreecommitdiff
path: root/node/Thread.cpp
diff options
context:
space:
mode:
authorAdam Ierymenko <adam.ierymenko@gmail.com>2013-07-04 16:56:19 -0400
committerAdam Ierymenko <adam.ierymenko@gmail.com>2013-07-04 16:56:19 -0400
commit150850b80012f852521c9935145cf966946334d5 (patch)
treec082369f2fef2515cfa2e4acf1b83250a3963158 /node/Thread.cpp
downloadinfinitytier-150850b80012f852521c9935145cf966946334d5.tar.gz
infinitytier-150850b80012f852521c9935145cf966946334d5.zip
New git repository for release - version 0.2.0 tagged
Diffstat (limited to 'node/Thread.cpp')
-rw-r--r--node/Thread.cpp192
1 files changed, 192 insertions, 0 deletions
diff --git a/node/Thread.cpp b/node/Thread.cpp
new file mode 100644
index 00000000..37a1a5a5
--- /dev/null
+++ b/node/Thread.cpp
@@ -0,0 +1,192 @@
+/*
+ * 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() :
+ suicidalThread(false),
+ _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);
+}
+
+void Thread::__intl_run()
+{
+ for(;;) {
+ _notInit = false;
+ this->main();
+ if (suicidalThread) {
+ delete this;
+ return;
+ }
+ 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() :
+ suicidalThread(false),
+ _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 (suicidalThread) {
+ delete this;
+ return;
+ }
+ 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