*/
#include <stddef.h>
#include <dpl/thread.h>
-#include <dpl/log/log.h>
+#include <dpl/log/wrt_log.h>
#include <sys/time.h>
#include <algorithm>
#include <dpl/assert.h>
static const size_t NANOSECONDS_PER_MICROSECOND =
static_cast<uint64_t>(1000);
-static const pthread_t g_mainThread = pthread_self();
+static const std::thread::id g_mainThread = std::this_thread::get_id();
class ThreadSpecific
{
bool g_TLSforMainCreated = false;
Thread::Thread() :
- m_thread(0),
+ m_thread(),
m_abandon(false),
m_running(false),
m_directInvoke(false)
bool Thread::IsMainThread()
{
- return (pthread_equal(pthread_self(), g_mainThread));
+ return (std::this_thread::get_id() == g_mainThread);
}
Thread *Thread::GetCurrentThread()
{
- if (pthread_equal(pthread_self(), g_mainThread)) {
+ if (std::this_thread::get_id() == g_mainThread) {
return NULL;
}
void *Thread::StaticThreadEntry(void *param)
{
- LogPedantic("Entered static thread entry");
+ char *errstr = NULL;
+ char errbuf[512] = {0,};
+ WrtLogD("Entered static thread entry");
// Retrieve context
Thread *This = static_cast<Thread *>(param);
int result = pthread_setspecific(g_threadSpecific.threadSpecific, This);
if (result != 0) {
- LogError("Failed to set threadSpecific. Error: " << strerror(result));
+#ifdef _GNU_SOURCE
+ errstr = strerror_r(result, errbuf, sizeof(errbuf));
+#else
+ strerror_r(result, errbuf, sizeof(errbuf));
+ errstr = errbuf;
+#endif
+ WrtLogE("Failed to set threadSpecific. Error: %s", errstr);
}
// Enter thread proc
// Critical section
{
// Leave running state
- Mutex::ScopedLock lock(&This->m_stateMutex);
+ std::lock_guard<std::mutex> lock(This->m_stateMutex);
This->m_running = false;
// Abandon thread
if (This->m_abandon) {
- LogPedantic("Thread was abandoned");
- pthread_detach(This->m_thread);
+ WrtLogD("Thread was abandoned");
+ This->m_thread.detach();
} else {
- LogPedantic("Thread is joinable");
+ WrtLogD("Thread is joinable");
}
}
int Thread::ThreadEntry()
{
- LogPedantic("Entered default thread entry");
+ WrtLogD("Entered default thread entry");
return Exec();
}
void Thread::ProcessEvents()
{
- LogPedantic("Processing events");
+ WrtLogD("Processing events");
// Steal current event list
InternalEventList stolenEvents;
// Enter event list critical section
{
- Mutex::ScopedLock lock(&m_eventMutex);
+ std::lock_guard<std::mutex> lock(m_eventMutex);
m_eventList.swap(stolenEvents);
m_eventInvoker.Reset();
}
// Process event list
- LogPedantic("Stolen " << stolenEvents.size() << " internal events");
+ WrtLogD("Stolen %u internal events", stolenEvents.size());
for (InternalEventList::iterator iterator = stolenEvents.begin();
iterator != stolenEvents.end();
{
// Critical section on timed events mutex
{
- Mutex::ScopedLock lock(&m_timedEventMutex);
+ std::lock_guard<std::mutex> lock(m_timedEventMutex);
// Get current time
unsigned long currentTimeMiliseconds = GetCurrentTimeMiliseconds();
// Info
- LogPedantic(
- "Processing timed events. Time now: " << currentTimeMiliseconds <<
- " ms");
+ WrtLogD("Processing timed events. Time now: %lu ms", currentTimeMiliseconds);
// All timed events are sorted chronologically
// Emit timed out events
m_timedEventVector.begin()->dueTimeMiliseconds)
{
// Info
- LogPedantic(
- "Transforming timed event into immediate event. Absolute due time: "
- <<
- (m_timedEventVector.begin()->registerTimeMiliseconds +
- m_timedEventVector.begin()->dueTimeMiliseconds) <<
- " ms");
+ WrtLogD("Transforming timed event into immediate event. Absolute due time: %lu ms",
+ (m_timedEventVector.begin()->registerTimeMiliseconds +
+ m_timedEventVector.begin()->dueTimeMiliseconds));
// Emit immediate event
PushEvent(m_timedEventVector.begin()->event,
int Thread::Exec()
{
- LogPedantic("Executing thread event processing");
+ WrtLogD("Executing thread event processing");
const std::size_t MIN_HANDLE_LIST_SIZE = 4;
// Critical section on timed events mutex
{
- Mutex::ScopedLock lock(&m_timedEventMutex);
+ std::lock_guard<std::mutex> lock(m_timedEventMutex);
if (!m_timedEventVector.empty()) {
unsigned long currentTimeMiliseconds =
}
// Info
- LogPedantic(
- "Thread loop minimum wait time: " << minimumWaitTime << " ms");
+ WrtLogD("Thread loop minimum wait time: %lu ms", minimumWaitTime);
// Do thread waiting
WaitableHandleIndexList waitableHandleIndexList =
if (waitableHandleIndexList.empty()) {
// Timeout occurred. Process timed events.
- LogPedantic("Timed event list elapsed invoker");
+ WrtLogD("Timed event list elapsed invoker");
ProcessTimedEvents();
continue;
}
{
size_t index = *waitableHandleIndexIterator;
- LogPedantic("Event loop triggered with index: " << index);
+ WrtLogD("Event loop triggered with index: %u", index);
switch (index) {
case 0:
if (m_directInvoke) {
m_directInvoke = false;
- LogPedantic("Handling direct invoker");
+ WrtLogD("Handling direct invoker");
// Update list
while (handleList.size() > MIN_HANDLE_LIST_SIZE) {
case 2:
// Timed event list changed
- LogPedantic("Timed event list changed invoker");
+ WrtLogD("Timed event list changed invoker");
ProcessTimedEvents();
// Reset timed event invoker
case 3:
// Waitable handle watch support invoker
- LogPedantic("Waitable handle watch invoker event occurred");
+ WrtLogD("Waitable handle watch invoker event occurred");
// First, remove all previous handles
while (handleList.size() > MIN_HANDLE_LIST_SIZE) {
// Handle invoker in waitable watch support
WaitableHandleWatchSupport::InvokerFinished();
- LogPedantic("Waitable handle watch invoker event handled");
+ WrtLogD("Waitable handle watch invoker event handled");
// Done
break;
default:
// Waitable event watch list
- LogPedantic("Waitable handle watch event occurred");
+ WrtLogD("Waitable handle watch event occurred");
// Handle event in waitable handle watch
{
if (m_directInvoke) {
m_directInvoke = false;
- LogPedantic("Handling direct invoker");
+ WrtLogD("Handling direct invoker");
// Update list
while (handleList.size() > MIN_HANDLE_LIST_SIZE) {
}
}
- LogPedantic("Waitable handle watch event handled");
+ WrtLogD("Waitable handle watch event handled");
// Done
break;
}
}
- LogPedantic("Leaving thread event processing");
+ WrtLogD("Leaving thread event processing");
return 0;
}
void Thread::Run()
{
- LogPedantic("Running thread");
+ WrtLogD("Running thread");
// Critical section
{
- Mutex::ScopedLock lock(&m_stateMutex);
+ std::lock_guard<std::mutex> lock(m_stateMutex);
if (m_running) {
return;
}
- // Try to create new thread
- if (pthread_create(&m_thread, NULL, &StaticThreadEntry, this) != 0) {
+ try{
+ m_thread = std::thread(StaticThreadEntry,this);
+ }catch(std::system_error e){
Throw(Exception::RunFailed);
}
m_running = true;
}
- LogPedantic("Thread run");
+ WrtLogD("Thread run");
}
void Thread::Quit()
{
- pthread_t joinableThread;
-
// Critical section
{
- Mutex::ScopedLock lock(&m_stateMutex);
+ std::lock_guard<std::mutex> lock(m_stateMutex);
// Is thread running ?
if (!m_running) {
return;
}
- LogPedantic("Quitting thread...");
+ WrtLogD("Quitting thread...");
// Do not abandon thread, we will join
m_abandon = false;
// Singal quit waitable event
m_quitEvent.Signal();
-
- // Copy joinable thread identifier, because
- // we are leaving critical section
- joinableThread = m_thread;
}
- // Wait for joinable thread
- void *result;
-
- if (pthread_join(joinableThread, &result) != 0) {
+ try{
+ m_thread.join();
+ }catch(std::system_error e){
Throw(Exception::QuitFailed);
}
- LogPedantic("Thread quit");
+ WrtLogD("Thread quit");
}
void Thread::PushEvent(void *event,
void *userParam)
{
// Enter event list critical section
- Mutex::ScopedLock lock(&m_eventMutex);
+ std::lock_guard<std::mutex> lock(m_eventMutex);
// Push new event
m_eventList.push_back(InternalEvent(event, userParam, eventDispatchProc,
// Trigger invoker
m_eventInvoker.Signal();
- LogPedantic("Event pushed and invoker signaled");
+ WrtLogD("Event pushed and invoker signaled");
}
void Thread::PushTimedEvent(void *event,
Assert(dueTimeSeconds >= 0.0);
// Enter timed event list critical section
- Mutex::ScopedLock lock(&m_timedEventMutex);
+ std::lock_guard<std::mutex> lock(m_timedEventMutex);
// Get current time
unsigned long currentTimeMiliseconds = GetCurrentTimeMiliseconds();
// Trigger invoker
m_timedEventInvoker.Signal();
- LogPedantic(
- "Timed event pushed and invoker signaled: due time: " <<
- dueTimeMiliseconds << " ms, absolute due time: " <<
- currentTimeMiliseconds + dueTimeMiliseconds << " ms");
+ WrtLogD("Timed event pushed and invoker signaled: "
+ "due time: %lu ms, absolute due time: %lu ms",
+ dueTimeMiliseconds, currentTimeMiliseconds + dueTimeMiliseconds);
}
Thread *Thread::GetInvokerThread()