diff options
author | Alexander Kriegisch <Alexander@Kriegisch.name> | 2022-02-28 07:07:08 +0700 |
---|---|---|
committer | Alexander Kriegisch <Alexander@Kriegisch.name> | 2022-03-23 15:39:14 +0700 |
commit | 3c80a365273b39c299cfdbc80c194cb9508e91a4 (patch) | |
tree | d2e41cf4d2ed875780bb97ecffee3c84e8f26742 /runtime | |
parent | d3a06a6942b6f69ce9b5b4403d3c1cf1803cf01e (diff) | |
download | aspectj-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>
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/src/main/java/org/aspectj/runtime/reflect/JoinPointImpl.java | 25 |
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) { |