This repository was archived by the owner on Jul 31, 2023. It is now read-only.
File tree Expand file tree Collapse file tree 3 files changed +30
-5
lines changed
Expand file tree Collapse file tree 3 files changed +30
-5
lines changed Original file line number Diff line number Diff line change @@ -67,6 +67,7 @@ class Context {
6767
6868 friend class ContextTestPeer ;
6969 friend class WithContext ;
70+ friend class ContextWrapper ;
7071 friend class ::opencensus::tags::ContextPeer;
7172 friend class ::opencensus::tags::WithTagMap;
7273 friend class ::opencensus::trace::ContextPeer;
Original file line number Diff line number Diff line change 1515#include " opencensus/context/context.h"
1616
1717#include < functional>
18+ #include < memory>
1819#include < utility>
1920
2021#include " absl/strings/str_cat.h"
2526namespace opencensus {
2627namespace context {
2728
29+ // Wrapper for per-thread Context, frees the Context on thread shutdown.
30+ class ContextWrapper {
31+ public:
32+ ContextWrapper () : ptr_(new Context) {}
33+ Context* get () { return ptr_.get (); }
34+
35+ private:
36+ std::unique_ptr<Context> ptr_;
37+ };
38+
39+ namespace {
40+ thread_local ContextWrapper g_wrapper;
41+ } // namespace
42+
2843Context::Context ()
2944 : tags_(opencensus::tags::TagMap({})),
3045 span_ (opencensus::trace::Span::BlankSpan()) {}
@@ -47,11 +62,7 @@ std::string Context::DebugString() const {
4762}
4863
4964// static
50- Context* Context::InternalMutableCurrent () {
51- static thread_local Context* thread_ctx = nullptr ;
52- if (thread_ctx == nullptr ) thread_ctx = new Context;
53- return thread_ctx;
54- }
65+ Context* Context::InternalMutableCurrent () { return g_wrapper.get (); }
5566
5667void swap (Context& a, Context& b) {
5768 using std::swap;
Original file line number Diff line number Diff line change 1616
1717#include < functional>
1818#include < iostream>
19+ #include < thread>
1920
2021#include " gtest/gtest.h"
2122#include " opencensus/tags/context_util.h"
@@ -87,6 +88,18 @@ TEST(ContextTest, WrapDoesNotLeak) {
8788 span.End ();
8889}
8990
91+ TEST (ContextTest, ThreadDoesNotLeak) {
92+ auto span = opencensus::trace::Span::StartSpan (" MySpan" );
93+ std::thread t ([span]() {
94+ // Leak-sanitizer (part of ASAN) throws an error if this leaks.
95+ opencensus::tags::WithTagMap wt (ExampleTagMap ());
96+ opencensus::trace::WithSpan ws (span);
97+ });
98+ t.join ();
99+ ExpectEmptyContext ();
100+ span.End ();
101+ }
102+
90103TEST (ContextTest, WrappedFnIsCopiable) {
91104 std::function<void ()> fn1, fn2;
92105 {
You can’t perform that action at this time.
0 commit comments