summaryrefslogtreecommitdiff
path: root/src/components/utils/src/threads/posix_thread.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/utils/src/threads/posix_thread.cc')
-rw-r--r--src/components/utils/src/threads/posix_thread.cc156
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);
}
}