Skip to content

Commit 2fa9986

Browse files
authored
When restoring a swapped out scope-stack, take defensive copy if the current thread is not the original. (#9403)
This mitigates a potential issue if the swapped out scope-stack is ever restored more than once on different threads.
1 parent 9aad755 commit 2fa9986

File tree

2 files changed

+8
-2
lines changed

2 files changed

+8
-2
lines changed

dd-trace-core/src/main/java/datadog/trace/core/scopemanager/ContinuableScopeManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ public Context swap(Context context) {
367367
ContinuableScope newScope;
368368
if (context instanceof ScopeContext) {
369369
// restore previously swapped context stack
370-
newStack = ((ScopeContext) context).scopeStack;
370+
newStack = ((ScopeContext) context).restore();
371371
newScope = newStack.top;
372372
} else if (context != Context.root()) {
373373
// start a new stack and record the new context as active

dd-trace-core/src/main/java/datadog/trace/core/scopemanager/ScopeContext.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66

77
/** Wraps a {@link ScopeStack} as a {@link Context} so it can be swapped back later. */
88
final class ScopeContext implements Context {
9-
final ScopeStack scopeStack;
9+
private final Thread originalThread = Thread.currentThread();
10+
private final ScopeStack scopeStack;
1011
private final Context context;
1112

1213
ScopeContext(ScopeStack scopeStack) {
@@ -18,6 +19,11 @@ private ScopeContext(ScopeStack scopeStack, Context context) {
1819
this.context = context;
1920
}
2021

22+
ScopeStack restore() {
23+
// take defensive copy of original scope stack when restoring on different thread
24+
return originalThread == Thread.currentThread() ? scopeStack : scopeStack.copy();
25+
}
26+
2127
@Nullable
2228
@Override
2329
public <T> T get(ContextKey<T> key) {

0 commit comments

Comments
 (0)