1
0
mirror of https://github.com/Zygo/bees.git synced 2025-05-18 05:45:45 +02:00
bees/src/bees-thread.cc
Zygo Blaxell 0710208354 BeesNote: thread naming fixes
Move pthread_setname_np to the same place we do pthread_getname_np.

Detect errors in pthread_getname_np--but don't throw an exception
because we would call ourself recursively from the exception handler
when it tries to log the exception.

Fix the order of set_name and the first BEESNOTE/BEESLOG call in threads,
closing small time intervals where logs have the wrong thread name,
and that wrong name becomes persistent for the thread.

Make the main thread's name "bees" because Linux kernel stack traces use
the pthread name of the main thread instead of the name of the process.

Anonymous threads get the process name (usually "bees").  We should not
have any such threads, but we do.  This appears to occur mostly during
exception stack unwinding.  GCC/pthread bug?

Fixes:  https://github.com/Zygo/bees/issues/51

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
2018-01-26 23:47:47 -05:00

89 lines
2.0 KiB
C++

#include "bees.h"
using namespace crucible;
using namespace std;
BeesThread::BeesThread(string name) :
m_name(name)
{
THROW_CHECK1(invalid_argument, name, !name.empty());
}
void
BeesThread::exec(function<void()> func)
{
m_timer.reset();
BEESLOGDEBUG("BeesThread exec " << m_name);
m_thread_ptr = make_shared<thread>([=]() {
BeesNote::set_name(m_name);
BEESLOGDEBUG("Starting thread " << m_name);
BEESNOTE("thread function");
Timer thread_time;
catch_all([&]() {
func();
});
BEESLOGDEBUG("Exiting thread " << m_name << ", " << thread_time << " sec");
});
}
BeesThread::BeesThread(string name, function<void()> func) :
m_name(name)
{
THROW_CHECK1(invalid_argument, name, !name.empty());
BEESLOGDEBUG("BeesThread construct " << m_name);
exec(func);
}
void
BeesThread::join()
{
if (!m_thread_ptr) {
BEESLOGDEBUG("Thread " << m_name << " no thread ptr");
return;
}
BEESLOGDEBUG("BeesThread::join " << m_name);
if (m_thread_ptr->joinable()) {
BEESLOGDEBUG("Joining thread " << m_name);
Timer thread_time;
m_thread_ptr->join();
BEESLOGDEBUG("Waited for " << m_name << ", " << thread_time << " sec");
} else if (!m_name.empty()) {
BEESLOGDEBUG("BeesThread " << m_name << " not joinable");
} else {
BEESLOGDEBUG("BeesThread else " << m_name);
}
}
void
BeesThread::set_name(const string &name)
{
m_name = name;
}
BeesThread::~BeesThread()
{
if (!m_thread_ptr) {
BEESLOGDEBUG("Thread " << m_name << " no thread ptr");
return;
}
BEESLOGDEBUG("BeesThread destructor " << m_name);
if (m_thread_ptr->joinable()) {
BEESLOGDEBUG("Cancelling thread " << m_name);
int rv = pthread_cancel(m_thread_ptr->native_handle());
if (rv) {
BEESLOGDEBUG("pthread_cancel returned " << strerror(-rv));
}
BEESLOGDEBUG("Waiting for thread " << m_name);
Timer thread_time;
m_thread_ptr->join();
BEESLOGDEBUG("Waited for " << m_name << ", " << thread_time << " sec");
} else if (!m_name.empty()) {
BEESLOGDEBUG("Thread " << m_name << " not joinable");
} else {
BEESLOGDEBUG("Thread destroy else " << m_name);
}
}