diff options
Diffstat (limited to 'src/components/utils/src/threads/posix_thread.cc')
-rw-r--r-- | src/components/utils/src/threads/posix_thread.cc | 156 |
1 files changed, 85 insertions, 71 deletions
diff --git a/src/components/utils/src/threads/posix_thread.cc b/src/components/utils/src/threads/posix_thread.cc index 8f481a82f3..5118e5291b 100644 --- a/src/components/utils/src/threads/posix_thread.cc +++ b/src/components/utils/src/threads/posix_thread.cc @@ -34,14 +34,11 @@ #include <limits.h> #include <stddef.h> #include <signal.h> - -#ifdef BUILD_TESTS -// Temporary fix for UnitTest until APPLINK-9987 is resolved -#include <unistd.h> -#endif +#include <pthread.h> +#include <algorithm> +#include <functional> #include "utils/threads/thread.h" -#include "pthread.h" #include "utils/atomic.h" #include "utils/threads/thread_delegate.h" #include "utils/logger.h" @@ -58,7 +55,8 @@ namespace threads { CREATE_LOGGERPTR_GLOBAL(logger_, "Utils") -size_t Thread::kMinStackSize = PTHREAD_STACK_MIN; /* Ubuntu : 16384 ; QNX : 256; */ +size_t Thread::kMinStackSize = + PTHREAD_STACK_MIN; /* Ubuntu : 16384 ; QNX : 256; */ void Thread::cleanup(void* arg) { LOG4CXX_AUTO_TRACE(logger_); @@ -82,42 +80,41 @@ void* Thread::threadFunc(void* arg) { // running = 1 // finalized = 1 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); - LOG4CXX_DEBUG(logger_, - "Thread #" << pthread_self() << " started successfully"); threads::Thread* thread = reinterpret_cast<Thread*>(arg); DCHECK(thread); pthread_cleanup_push(&cleanup, thread); - thread->state_lock_.Acquire(); - thread->state_cond_.Broadcast(); + thread->state_lock_.Acquire(); + thread->state_cond_.Broadcast(); - while (!thread->finalized_) { - LOG4CXX_DEBUG(logger_, "Thread #" << pthread_self() << " iteration"); - thread->run_cond_.Wait(thread->state_lock_); - LOG4CXX_DEBUG( - logger_, - "Thread #" << pthread_self() << " execute. " << "stopped_ = " << thread->stopped_ << "; finalized_ = " << thread->finalized_); - if (!thread->stopped_ && !thread->finalized_) { - thread->isThreadRunning_ = true; - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); - pthread_testcancel(); - - thread->state_lock_.Release(); - thread->delegate_->threadMain(); - thread->state_lock_.Acquire(); - - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); - thread->isThreadRunning_ = false; - } - thread->state_cond_.Broadcast(); - LOG4CXX_DEBUG(logger_, - "Thread #" << pthread_self() << " finished iteration"); + while (!thread->finalized_) { + LOG4CXX_DEBUG(logger_, "Thread #" << pthread_self() << " iteration"); + thread->run_cond_.Wait(thread->state_lock_); + LOG4CXX_DEBUG(logger_, + "Thread #" << pthread_self() << " execute. " + << "stopped_ = " << thread->stopped_ + << "; finalized_ = " << thread->finalized_); + if (!thread->stopped_ && !thread->finalized_) { + thread->isThreadRunning_ = true; + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + pthread_testcancel(); + + thread->state_lock_.Release(); + thread->delegate_->threadMain(); + thread->state_lock_.Acquire(); + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); + thread->isThreadRunning_ = false; } + thread->state_cond_.Broadcast(); + LOG4CXX_DEBUG(logger_, + "Thread #" << pthread_self() << " finished iteration"); + } - thread->state_lock_.Release(); - pthread_cleanup_pop(1); + thread->state_lock_.Release(); + pthread_cleanup_pop(1); LOG4CXX_DEBUG(logger_, "Thread #" << pthread_self() << " exited successfully"); @@ -130,22 +127,22 @@ void Thread::SetNameForId(const PlatformThreadHandle& thread_id, name.erase(THREAD_NAME_SIZE); const int rc = pthread_setname_np(thread_id, name.c_str()); if (rc != EOK) { - LOG4CXX_WARN( - logger_, - "Couldn't set pthread name \"" << name << "\", error code " << rc << " (" << strerror(rc) << ")"); + LOG4CXX_WARN(logger_, + "Couldn't set pthread name \"" << name << "\", error code " + << rc << " (" << strerror(rc) + << ")"); } } Thread::Thread(const char* name, ThreadDelegate* delegate) - : name_(name ? name : "undefined"), - delegate_(delegate), - handle_(0), - thread_options_(), - isThreadRunning_(0), - stopped_(false), - finalized_(false), - thread_created_(false) { -} + : name_(name ? name : "undefined") + , delegate_(delegate) + , handle_(0) + , thread_options_() + , isThreadRunning_(0) + , stopped_(false) + , finalized_(false) + , thread_created_(false) {} bool Thread::start() { return start(thread_options_); @@ -155,6 +152,10 @@ PlatformThreadHandle Thread::CurrentId() { return pthread_self(); } +bool Thread::IsCurrentThread() const { + return pthread_equal(CurrentId(), thread_handle()); +} + bool Thread::start(const ThreadOptions& options) { LOG4CXX_AUTO_TRACE(logger_); @@ -171,9 +172,9 @@ bool Thread::start(const ThreadOptions& options) { } if (isThreadRunning_) { - LOG4CXX_TRACE( - logger_, - "EXIT thread "<< name_ << " #" << handle_ << " is already running"); + LOG4CXX_TRACE(logger_, + "EXIT thread " << name_ << " #" << handle_ + << " is already running"); return true; } @@ -182,17 +183,20 @@ bool Thread::start(const ThreadOptions& options) { pthread_attr_t attributes; int pthread_result = pthread_attr_init(&attributes); if (pthread_result != EOK) { - LOG4CXX_WARN( - logger_, - "Couldn't init pthread attributes. Error code = " << pthread_result << " (\"" << strerror(pthread_result) << "\")"); + LOG4CXX_WARN(logger_, + "Couldn't init pthread attributes. Error code = " + << pthread_result << " (\"" << strerror(pthread_result) + << "\")"); } if (!thread_options_.is_joinable()) { - pthread_result = pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED); + pthread_result = + pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED); if (pthread_result != EOK) { - LOG4CXX_WARN( - logger_, - "Couldn't set detach state attribute. Error code = " << pthread_result << " (\"" << strerror(pthread_result) << "\")"); + LOG4CXX_WARN(logger_, + "Couldn't set detach state attribute. Error code = " + << pthread_result << " (\"" << strerror(pthread_result) + << "\")"); thread_options_.is_joinable(false); } } @@ -201,13 +205,14 @@ bool Thread::start(const ThreadOptions& options) { if (stack_size >= Thread::kMinStackSize) { pthread_result = pthread_attr_setstacksize(&attributes, stack_size); if (pthread_result != EOK) { - LOG4CXX_WARN( - logger_, - "Couldn't set stacksize = " << stack_size << ". Error code = " << pthread_result << " (\"" << strerror(pthread_result) << "\")"); + LOG4CXX_WARN(logger_, + "Couldn't set stacksize = " + << stack_size << ". Error code = " << pthread_result + << " (\"" << strerror(pthread_result) << "\")"); } - } - else { - ThreadOptions thread_options_temp(Thread::kMinStackSize, thread_options_.is_joinable()); + } else { + ThreadOptions thread_options_temp(Thread::kMinStackSize, + thread_options_.is_joinable()); thread_options_ = thread_options_temp; } @@ -222,28 +227,33 @@ bool Thread::start(const ThreadOptions& options) { state_cond_.Wait(auto_lock); thread_created_ = true; } else { - LOG4CXX_ERROR( - logger_, - "Couldn't create thread " << name_ << ". Error code = " << pthread_result << " (\"" << strerror(pthread_result) << "\")"); + LOG4CXX_ERROR(logger_, + "Couldn't create thread " + << name_ << ". Error code = " << pthread_result + << " (\"" << strerror(pthread_result) << "\")"); } } stopped_ = false; run_cond_.NotifyOne(); - LOG4CXX_DEBUG( - logger_, - "Thread " << name_ << " #" << handle_ << " started. pthread_result = " << pthread_result); + LOG4CXX_DEBUG(logger_, + "Thread " << name_ << " #" << handle_ << " started." + << " pthread_result = " << pthread_result); pthread_attr_destroy(&attributes); return pthread_result == EOK; } +void Thread::yield() { + sched_yield(); +} + void Thread::stop() { LOG4CXX_AUTO_TRACE(logger_); sync_primitives::AutoLock auto_lock(state_lock_); stopped_ = true; - LOG4CXX_DEBUG(logger_, "Stopping thread #" << handle_ - << " \"" << name_ << " \""); + LOG4CXX_DEBUG(logger_, + "Stopping thread #" << handle_ << " \"" << name_ << "\""); if (delegate_ && isThreadRunning_) { delegate_->exitThreadMain(); @@ -255,7 +265,7 @@ void Thread::stop() { void Thread::join() { LOG4CXX_AUTO_TRACE(logger_); - DCHECK(!pthread_equal(pthread_self(), handle_)); + DCHECK_OR_RETURN_VOID(!IsCurrentThread()); stop(); @@ -263,6 +273,10 @@ void Thread::join() { run_cond_.NotifyOne(); if (isThreadRunning_) { if (!pthread_equal(pthread_self(), handle_)) { + LOG4CXX_DEBUG(logger_, + "Waiting for #" << handle_ + << " finished iteration in thread #" + << pthread_self()); state_cond_.Wait(auto_lock); } } |