mirror of
https://github.com/Zygo/bees.git
synced 2025-05-18 05:45:45 +02:00
bees: fix deadlock in thread status reporting
"s_name" was a thread_local variable, not static, and did not require a mutex to protect access. A deadlock is possible if a thread triggers an exception with a handler that attempts to log a message (as the top-level exception handler in bees does). Remove multiple unnecessary mutex locks. Rename the thread_local variables to make their scope clearer. Signed-off-by: Zygo Blaxell <bees@furryterror.org>
This commit is contained in:
parent
382f8bf06a
commit
9f120e326b
37
src/bees.cc
37
src/bees.cc
@ -46,7 +46,7 @@ do_cmd_help(const char **argv)
|
|||||||
|
|
||||||
RateLimiter bees_info_rate_limit(BEES_INFO_RATE, BEES_INFO_BURST);
|
RateLimiter bees_info_rate_limit(BEES_INFO_RATE, BEES_INFO_BURST);
|
||||||
|
|
||||||
thread_local BeesTracer *BeesTracer::s_next_tracer = nullptr;
|
thread_local BeesTracer *BeesTracer::tl_next_tracer = nullptr;
|
||||||
|
|
||||||
BeesTracer::~BeesTracer()
|
BeesTracer::~BeesTracer()
|
||||||
{
|
{
|
||||||
@ -56,20 +56,20 @@ BeesTracer::~BeesTracer()
|
|||||||
BEESLOG("--- END TRACE --- exception ---");
|
BEESLOG("--- END TRACE --- exception ---");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s_next_tracer = m_next_tracer;
|
tl_next_tracer = m_next_tracer;
|
||||||
}
|
}
|
||||||
|
|
||||||
BeesTracer::BeesTracer(function<void()> f) :
|
BeesTracer::BeesTracer(function<void()> f) :
|
||||||
m_func(f)
|
m_func(f)
|
||||||
{
|
{
|
||||||
m_next_tracer = s_next_tracer;
|
m_next_tracer = tl_next_tracer;
|
||||||
s_next_tracer = this;
|
tl_next_tracer = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BeesTracer::trace_now()
|
BeesTracer::trace_now()
|
||||||
{
|
{
|
||||||
BeesTracer *tp = s_next_tracer;
|
BeesTracer *tp = tl_next_tracer;
|
||||||
BEESLOG("--- BEGIN TRACE ---");
|
BEESLOG("--- BEGIN TRACE ---");
|
||||||
while (tp) {
|
while (tp) {
|
||||||
tp->m_func();
|
tp->m_func();
|
||||||
@ -78,18 +78,19 @@ BeesTracer::trace_now()
|
|||||||
BEESLOG("--- END TRACE ---");
|
BEESLOG("--- END TRACE ---");
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_local BeesNote *BeesNote::s_next = nullptr;
|
thread_local BeesNote *BeesNote::tl_next = nullptr;
|
||||||
mutex BeesNote::s_mutex;
|
mutex BeesNote::s_mutex;
|
||||||
map<pid_t, BeesNote*> BeesNote::s_status;
|
map<pid_t, BeesNote*> BeesNote::s_status;
|
||||||
thread_local string BeesNote::s_name;
|
thread_local string BeesNote::tl_name;
|
||||||
|
|
||||||
BeesNote::~BeesNote()
|
BeesNote::~BeesNote()
|
||||||
{
|
{
|
||||||
|
tl_next = m_prev;
|
||||||
|
if (tl_next) {
|
||||||
unique_lock<mutex> lock(s_mutex);
|
unique_lock<mutex> lock(s_mutex);
|
||||||
s_next = m_prev;
|
s_status[gettid()] = tl_next;
|
||||||
if (s_next) {
|
|
||||||
s_status[gettid()] = s_next;
|
|
||||||
} else {
|
} else {
|
||||||
|
unique_lock<mutex> lock(s_mutex);
|
||||||
s_status.erase(gettid());
|
s_status.erase(gettid());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -97,28 +98,26 @@ BeesNote::~BeesNote()
|
|||||||
BeesNote::BeesNote(function<void(ostream &os)> f) :
|
BeesNote::BeesNote(function<void(ostream &os)> f) :
|
||||||
m_func(f)
|
m_func(f)
|
||||||
{
|
{
|
||||||
|
m_name = tl_name;
|
||||||
|
m_prev = tl_next;
|
||||||
|
tl_next = this;
|
||||||
unique_lock<mutex> lock(s_mutex);
|
unique_lock<mutex> lock(s_mutex);
|
||||||
m_name = s_name;
|
s_status[gettid()] = tl_next;
|
||||||
m_prev = s_next;
|
|
||||||
s_next = this;
|
|
||||||
s_status[gettid()] = s_next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BeesNote::set_name(const string &name)
|
BeesNote::set_name(const string &name)
|
||||||
{
|
{
|
||||||
unique_lock<mutex> lock(s_mutex);
|
tl_name = name;
|
||||||
s_name = name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string
|
string
|
||||||
BeesNote::get_name()
|
BeesNote::get_name()
|
||||||
{
|
{
|
||||||
unique_lock<mutex> lock(s_mutex);
|
if (tl_name.empty()) {
|
||||||
if (s_name.empty()) {
|
|
||||||
return "bees";
|
return "bees";
|
||||||
} else {
|
} else {
|
||||||
return s_name;
|
return tl_name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +184,7 @@ class BeesTracer {
|
|||||||
function<void()> m_func;
|
function<void()> m_func;
|
||||||
BeesTracer *m_next_tracer = 0;
|
BeesTracer *m_next_tracer = 0;
|
||||||
|
|
||||||
thread_local static BeesTracer *s_next_tracer;
|
thread_local static BeesTracer *tl_next_tracer;
|
||||||
public:
|
public:
|
||||||
BeesTracer(function<void()> f);
|
BeesTracer(function<void()> f);
|
||||||
~BeesTracer();
|
~BeesTracer();
|
||||||
@ -200,8 +200,8 @@ class BeesNote {
|
|||||||
static mutex s_mutex;
|
static mutex s_mutex;
|
||||||
static map<pid_t, BeesNote*> s_status;
|
static map<pid_t, BeesNote*> s_status;
|
||||||
|
|
||||||
thread_local static BeesNote *s_next;
|
thread_local static BeesNote *tl_next;
|
||||||
thread_local static string s_name;
|
thread_local static string tl_name;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BeesNote(function<void(ostream &)> f);
|
BeesNote(function<void(ostream &)> f);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user