summaryrefslogtreecommitdiff
path: root/src/3rd_party-static/message_broker/src/lib_messagebroker/system.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rd_party-static/message_broker/src/lib_messagebroker/system.cpp')
-rw-r--r--src/3rd_party-static/message_broker/src/lib_messagebroker/system.cpp267
1 files changed, 267 insertions, 0 deletions
diff --git a/src/3rd_party-static/message_broker/src/lib_messagebroker/system.cpp b/src/3rd_party-static/message_broker/src/lib_messagebroker/system.cpp
new file mode 100644
index 0000000000..456362f9d8
--- /dev/null
+++ b/src/3rd_party-static/message_broker/src/lib_messagebroker/system.cpp
@@ -0,0 +1,267 @@
+/*
+ * JsonRpc-Cpp - JSON-RPC implementation.
+ * Copyright (C) 2008-2011 Sebastien Vincent <sebastien.vincent@cppextrem.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file system.cpp
+ * \brief System utils.
+ * \author Sebastien Vincent
+ */
+
+#include <time.h>
+#include <signal.h>
+
+#include "system.h"
+
+namespace System {
+
+void msleep(unsigned long ms) {
+#ifdef _WIN32
+ Sleep(ms);
+#else
+ /* Unix */
+ struct timespec req;
+ req.tv_sec = ms / 1000;
+ req.tv_nsec = (ms % 1000) * 1000000;
+ nanosleep(&req, NULL);
+#endif
+}
+
+ThreadArg::~ThreadArg() {
+}
+
+#ifndef WIN32
+
+/* POSIX specific part for thread and mutex */
+
+Thread::Thread(ThreadArg* arg) {
+ m_arg = arg;
+}
+
+Thread::~Thread() {
+ delete m_arg;
+}
+
+bool Thread::Start(bool detach) {
+ pthread_attr_t attr;
+ int ret = -1;
+
+ /* must have valid object argument */
+ if (m_arg == NULL) {
+ return false;
+ }
+
+ /* set the detach state value */
+ if (pthread_attr_init(&attr) != 0) {
+ return false;
+ }
+
+ if (pthread_attr_setdetachstate(&attr, detach ? PTHREAD_CREATE_DETACHED : PTHREAD_CREATE_JOINABLE) != 0) {
+ pthread_attr_destroy(&attr);
+ return false;
+ }
+
+ /* create thread */
+ ret = pthread_create(&m_id, &attr, &Thread::Call, this);
+ pthread_setname_np(m_id, "MB Thread");
+ pthread_attr_destroy(&attr);
+ return ret == 0;
+}
+
+bool Thread::Stop() {
+ pthread_cancel(m_id);
+ return false;// Android does not support 'pthread_cancel';
+}
+
+bool Thread::Join(void** ret) {
+ return pthread_join(m_id, ret) == 0;
+}
+
+void* Thread::Call(void* arg) {
+ // Disable system signals receiving in thread
+ // by setting empty signal mask
+ // (system signals processes only in the main thread)
+ sigset_t set;
+ sigfillset(&set);
+ pthread_sigmask(SIG_SETMASK, &set, NULL);
+
+ Thread* thread = static_cast<Thread*>(arg);
+
+ /* call our specific object method */
+ return thread->m_arg->Call();
+}
+
+Mutex::Mutex() {
+ pthread_mutexattr_t attr;
+
+ pthread_mutexattr_init(&attr);
+ pthread_mutex_init(&m_mutex, &attr);
+ pthread_mutexattr_destroy(&attr);
+}
+
+Mutex::~Mutex() {
+ pthread_mutex_destroy(&m_mutex);
+}
+
+bool Mutex::Lock() {
+ return !pthread_mutex_lock(&m_mutex);
+}
+
+bool Mutex::Unlock() {
+ return !pthread_mutex_unlock(&m_mutex);
+}
+
+
+// Based on Binary Semaphores example at
+// http://www.mathcs.emory.edu/~cheung/Courses/455/Syllabus/5c-pthreads/sync.html
+BinarySemaphore::BinarySemaphore() :
+ m_mutex(PTHREAD_MUTEX_INITIALIZER),
+ m_cond(PTHREAD_COND_INITIALIZER),
+ m_isUp(false) {
+ pthread_mutex_init(&m_mutex, NULL);
+ pthread_cond_init(&m_cond, NULL);
+}
+
+BinarySemaphore::~BinarySemaphore() {
+ pthread_cond_destroy(&m_cond);
+ pthread_mutex_destroy(&m_mutex);
+}
+
+void BinarySemaphore::Wait() {
+ // try to get exclusive access to the flag
+ pthread_mutex_lock(&m_mutex);
+ // success: no other thread can get here unless
+ // the current thread unlocks the mutex
+
+ // wait until the flag is up
+ while (!m_isUp) {
+ pthread_cond_wait(&m_cond, &m_mutex);
+ // when the current thread executes this, it will be
+ // blocked on m_cond, and automatically unlocks the
+ // mutex! Unlocking the mutex will let other threads
+ // in to test the flag.
+ }
+
+ // here we know that flag is upand this thread has now
+ // successfully passed the semaphore
+
+ // this will cause all other threads that execute the Wait()
+ // call to wait in the above loop
+ m_isUp = false;
+
+ // release the exclusive access to the flag
+ pthread_mutex_unlock(&m_mutex);
+}
+
+void BinarySemaphore::Notify() {
+ // try to get exclusive access to the flag
+ pthread_mutex_lock(&m_mutex);
+
+ // this call may resume a thread that is blocked on m_cond
+ // (in the Wait() call). if there was none, this does nothing
+ pthread_cond_signal(&m_cond);
+
+ // up the flag
+ m_isUp = true;
+
+ // release the exclusive access to the flag
+ pthread_mutex_unlock(&m_mutex);
+}
+
+#else
+
+/* Windows specific part for thread and mutex */
+
+Thread::Thread(ThreadArg* arg) {
+ m_arg = arg;
+}
+
+Thread::~Thread() {
+ delete m_arg;
+}
+
+bool Thread::Start(bool detach) {
+ detach = detach; /* unused parameter */
+
+ m_id = CreateThread(NULL, /* default security attributes */
+ 0, /* use default stack size */
+ &Thread::Call, /* thread function name */
+ this, /* argument to thread function */
+ 0, /* use default creation flags */
+ NULL); /* returns the thread identifier */
+
+ return m_id != NULL;
+}
+
+bool Thread::Stop() {
+ return TerminateThread(m_id, (DWORD) - 1);
+}
+
+bool Thread::Join(void** ret) {
+ DWORD val = 0;
+ WaitForSingleObject(m_id, INFINITE);
+ GetExitCodeThread(m_id, &val);
+ CloseHandle(m_id);
+ m_id = NULL;
+ *ret = (void*)val;
+ return true;
+}
+
+DWORD WINAPI Thread::Call(LPVOID arg) {
+ Thread* thread = static_cast<Thread*>(arg);
+
+ /* call our specific object method */
+#ifdef _WIN64
+ return (DWORD64)thread->m_arg->Call();
+#else
+ return (DWORD)thread->m_arg->Call();
+#endif
+}
+
+Mutex::Mutex() {
+ m_mutex = CreateMutex(NULL, /* no security attribute */
+ 0, /* not initial owner (i.e. no first lock) */
+ NULL); /* no name */
+}
+
+Mutex::~Mutex() {
+ /* free mutex */
+ if (m_mutex) {
+ CloseHandle(m_mutex);
+ }
+}
+
+bool Mutex::Lock() {
+ if (!m_mutex) {
+ return false;
+ }
+
+ return (WaitForSingleObject(m_mutex, INFINITE) == WAIT_OBJECT_0);
+}
+
+bool Mutex::Unlock() {
+ if (!m_mutex) {
+ return false;
+ }
+
+ return ReleaseMutex(m_mutex);
+}
+
+#endif
+
+} /* namespace System */
+