From 150850b80012f852521c9935145cf966946334d5 Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Thu, 4 Jul 2013 16:56:19 -0400 Subject: New git repository for release - version 0.2.0 tagged --- node/Thread.cpp | 192 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 node/Thread.cpp (limited to 'node/Thread.cpp') 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 . + * + * -- + * + * 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 +#include +#include +#include +#include +#include + +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 +#include +#include + +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 -- cgit v1.2.3