aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Kriegisch <Alexander@Kriegisch.name>2022-02-28 07:07:08 +0700
committerAlexander Kriegisch <Alexander@Kriegisch.name>2022-03-23 15:39:14 +0700
commit3c80a365273b39c299cfdbc80c194cb9508e91a4 (patch)
treed2e41cf4d2ed875780bb97ecffee3c84e8f26742
parentd3a06a6942b6f69ce9b5b4403d3c1cf1803cf01e (diff)
downloadaspectj-3c80a365273b39c299cfdbc80c194cb9508e91a4.tar.gz
aspectj-3c80a365273b39c299cfdbc80c194cb9508e91a4.zip
Make Stack<AroundClosure> in JoinPointImpl InheritableThreadLocal
In case of asynchronous proceeding for nested around-advice, child threads need copies of the original around-closure stack. Otherwise, the target method thread will have popped the stack empty after unwinding. Fixes #128. Signed-off-by: Alexander Kriegisch <Alexander@Kriegisch.name>
-rw-r--r--runtime/src/main/java/org/aspectj/runtime/reflect/JoinPointImpl.java25
1 files changed, 19 insertions, 6 deletions
diff --git a/runtime/src/main/java/org/aspectj/runtime/reflect/JoinPointImpl.java b/runtime/src/main/java/org/aspectj/runtime/reflect/JoinPointImpl.java
index bb09e6869..851a8b3dc 100644
--- a/runtime/src/main/java/org/aspectj/runtime/reflect/JoinPointImpl.java
+++ b/runtime/src/main/java/org/aspectj/runtime/reflect/JoinPointImpl.java
@@ -79,6 +79,18 @@ class JoinPointImpl implements ProceedingJoinPoint {
}
}
+ static class InheritableThreadLocalAroundClosureStack extends InheritableThreadLocal<Stack<AroundClosure>> {
+ @Override
+ protected Stack<AroundClosure> initialValue() {
+ return new Stack<>();
+ }
+
+ @Override
+ protected Stack<AroundClosure> childValue(Stack<AroundClosure> parentValue) {
+ return (Stack<AroundClosure>) parentValue.clone();
+ }
+ }
+
Object _this;
Object target;
Object[] args;
@@ -140,7 +152,7 @@ class JoinPointImpl implements ProceedingJoinPoint {
// will either be using arc or arcs but not both. arcs being non-null
// indicates it is in use (even if an empty stack)
private AroundClosure arc = null;
- private Stack<AroundClosure> arcs = null;
+ private InheritableThreadLocalAroundClosureStack arcs = null;
public void set$AroundClosure(AroundClosure arc) {
this.arc = arc;
@@ -149,12 +161,12 @@ class JoinPointImpl implements ProceedingJoinPoint {
public void stack$AroundClosure(AroundClosure arc) {
// If input parameter arc is null this is the 'unlink' call from AroundClosure
if (arcs == null) {
- arcs = new Stack<>();
+ arcs = new InheritableThreadLocalAroundClosureStack();
}
if (arc==null) {
- this.arcs.pop();
+ this.arcs.get().pop();
} else {
- this.arcs.push(arc);
+ this.arcs.get().push(arc);
}
}
@@ -167,7 +179,8 @@ class JoinPointImpl implements ProceedingJoinPoint {
return arc.run(arc.getState());
}
} else {
- return arcs.peek().run(arcs.peek().getState());
+ final AroundClosure ac = arcs.get().peek();
+ return ac.run(ac.getState());
}
}
@@ -177,7 +190,7 @@ class JoinPointImpl implements ProceedingJoinPoint {
if (arcs == null) {
ac = arc;
} else {
- ac = arcs.peek();
+ ac = arcs.get().peek();
}
if (ac == null) {