Skip to content

Commit fc11418

Browse files
committed
Introduce ContextHolder to hold/update current context without the overhead of ThreadLocal
1 parent f453621 commit fc11418

1 file changed

Lines changed: 19 additions & 15 deletions

File tree

components/context/src/main/java/datadog/context/ThreadLocalContextManager.java

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@
88
final class ThreadLocalContextManager implements ContextManager {
99
static final ThreadLocalContextManager INSTANCE = new ThreadLocalContextManager();
1010

11-
private static final ThreadLocal<Context[]> CURRENT_HOLDER =
12-
ThreadLocal.withInitial(() -> new Context[] {Context.root()});
11+
private static final ThreadLocal<ContextHolder> CONTEXT_HOLDER =
12+
ThreadLocal.withInitial(ContextHolder::new);
1313

1414
private final Object listenersWriteLock = new Object();
15-
private volatile ContextListener[] listeners = {};
15+
volatile ContextListener[] listeners = {};
1616

1717
@Override
1818
public Context current() {
19-
return CURRENT_HOLDER.get()[0];
19+
return CONTEXT_HOLDER.get().current;
2020
}
2121

2222
@Override
@@ -25,9 +25,9 @@ public ContextScope attach(Context context) {
2525
}
2626

2727
ContextScope doAttach(Context context, @Nullable ContextContinuationImpl continuation) {
28-
Context[] holder = CURRENT_HOLDER.get();
28+
ContextHolder holder = CONTEXT_HOLDER.get();
2929

30-
Context previous = holder[0];
30+
Context previous = holder.current;
3131
if (context == previous) {
3232
if (continuation != null) {
3333
// already attached, safe to release early to avoid resource leak
@@ -38,7 +38,7 @@ ContextScope doAttach(Context context, @Nullable ContextContinuationImpl continu
3838

3939
ContextListener[] ls = listeners;
4040
notifyDetach(previous, ls);
41-
holder[0] = context;
41+
holder.current = context;
4242
notifyAttach(context, ls);
4343

4444
if (continuation == null) {
@@ -50,16 +50,16 @@ ContextScope doAttach(Context context, @Nullable ContextContinuationImpl continu
5050

5151
@Override
5252
public Context swap(Context context) {
53-
Context[] holder = CURRENT_HOLDER.get();
53+
ContextHolder holder = CONTEXT_HOLDER.get();
5454

55-
Context previous = holder[0];
55+
Context previous = holder.current;
5656
if (context == previous) {
5757
return previous;
5858
}
5959

6060
ContextListener[] ls = listeners;
6161
notifyDetach(previous, ls);
62-
holder[0] = context;
62+
holder.current = context;
6363
notifyAttach(context, ls);
6464

6565
return previous;
@@ -142,12 +142,12 @@ static void notifyRelease(Context context, ContextListener[] listeners) {
142142
private static class ContextScopeImpl implements ContextScope {
143143

144144
private final Context context;
145-
private final Context[] holder;
145+
private final ContextHolder holder;
146146
private final Context previous;
147147

148148
private boolean closed;
149149

150-
ContextScopeImpl(Context context, Context[] holder, Context previous) {
150+
ContextScopeImpl(Context context, ContextHolder holder, Context previous) {
151151
this.context = context;
152152
this.holder = holder;
153153
this.previous = previous;
@@ -162,10 +162,10 @@ public final Context context() {
162162
public void close() {
163163
if (!closed) {
164164
// check for out-of-order close to avoid corrupting the current state
165-
if (context == holder[0]) {
165+
if (context == holder.current) {
166166
ContextListener[] ls = INSTANCE.listeners;
167167
notifyDetach(context, ls);
168-
holder[0] = previous;
168+
holder.current = previous;
169169
notifyAttach(previous, ls);
170170
closed = true;
171171
}
@@ -178,7 +178,7 @@ private static final class ResumedScopeImpl extends ContextScopeImpl {
178178

179179
ResumedScopeImpl(
180180
Context context,
181-
Context[] holder,
181+
ContextHolder holder,
182182
Context previous,
183183
@Nullable ContextContinuationImpl continuation) {
184184
super(context, holder, previous);
@@ -285,4 +285,8 @@ void releaseOnScopeClose() {
285285
} /* else there are outstanding resumes or hold is in place */
286286
}
287287
}
288+
289+
private static final class ContextHolder {
290+
Context current = Context.root();
291+
}
288292
}

0 commit comments

Comments
 (0)