1
0
mirror of https://github.com/Zygo/bees.git synced 2025-05-17 13:25:45 +02:00
bees/src/bees-thread.cc
Zygo Blaxell db65031c2b context: get rid of all instances of pthread_cancel
pthread_cancel doesn't really work properly.  It was only being used in
bees to bring threads to a stop if the BeesContext is destroyed early.
It is frequently implicated in core dump reports because of the fragility
of the C++ iostream / C stdio / library infrastructure, particularly
surrounding upgrades on the host running bees.  The pthread_cancel call
itself often simply fails even when it doesn't call terminate().

Defer creation of the status and progress threads until after the
BeesContext::start method is invoked.  At that point, the existing
ask-threads-nicely-to-stop code is up and running, and normal condvars
can be used to bring bees to a stop, without having to resort to
pthread_cancel.

Since we're deleting half of the BeesContext constructor in this change,
let's remove the other half too, and put an end to the deprecated support
for multiple BeesContexts sharing a process.  It's still possible to run
multiple BeesContexts, but they will not share a FD cache.  This will
allow the FD cache's keys to become smaller and hopefully save some
memory later on.

Fixes: #171

Signed-off-by: Zygo Blaxell <bees@furryterror.org>
2021-04-28 21:42:03 -04:00

84 lines
1.8 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("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);
}
}