make logging not leak Context objects when threads die
Change-Id: I629575c118ab666818bed5952dbc3bedd98e250d
diff --git a/aos/linux_code/logging/linux_interface.cc b/aos/linux_code/logging/linux_interface.cc
index 0945ddd..0040e94 100644
--- a/aos/linux_code/logging/linux_interface.cc
+++ b/aos/linux_code/logging/linux_interface.cc
@@ -2,6 +2,7 @@
#include <sys/prctl.h>
+#include "aos/linux_code/complex_thread_local.h"
#include "aos/linux_code/thread_local.h"
#include "aos/common/die.h"
@@ -39,23 +40,23 @@
return process_name + '.' + thread_name;
}
-AOS_THREAD_LOCAL Context *my_context(nullptr);
+::aos::ComplexThreadLocal<Context> my_context;
-// A temporary stash for Context objects that we're going to delete ASAP. The
+// True if we're going to delete the current Context object ASAP. The
// reason for doing this instead of just deleting them is that tsan (at least)
// doesn't like it when pthread_atfork handlers do complicated stuff and it's
// not a great idea anyways.
-AOS_THREAD_LOCAL Context *old_context(nullptr);
+AOS_THREAD_LOCAL bool delete_current_context(false);
} // namespace
Context *Context::Get() {
- if (__builtin_expect(my_context == nullptr, 0)) {
- if (old_context != nullptr) {
- delete old_context;
- old_context = nullptr;
- }
- my_context = new Context();
+ if (__builtin_expect(delete_current_context, false)) {
+ my_context.Clear();
+ delete_current_context = false;
+ }
+ if (__builtin_expect(!my_context.created(), false)) {
+ my_context.Create();
my_context->name = GetMyName();
if (my_context->name.size() + 1 > sizeof(LogMessage::name)) {
Die("logging: process/thread name '%s' is too long\n",
@@ -63,17 +64,11 @@
}
my_context->source = getpid();
}
- return my_context;
+ return my_context.get();
}
void Context::Delete() {
- if (my_context != nullptr) {
- if (old_context != nullptr) {
- delete old_context;
- }
- old_context = my_context;
- my_context = nullptr;
- }
+ delete_current_context = true;
}
} // namespace internal