Skip to content

Commit

Permalink
Make Stack<AroundClosure> in JoinPointImpl InheritableThreadLocal
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
kriegaex committed Mar 23, 2022
1 parent d3a06a6 commit 3c80a36
Showing 1 changed file with 19 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,18 @@ public EnclosingStaticPartImpl(int count, String kind, Signature signature, Sour
}
}

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;
Expand Down Expand Up @@ -140,7 +152,7 @@ public final String toLongString() {
// 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;
Expand All @@ -149,12 +161,12 @@ public final String toLongString() {
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);
}
}

Expand All @@ -167,7 +179,8 @@ public Object proceed() throws Throwable {
return arc.run(arc.getState());
}
} else {
return arcs.peek().run(arcs.peek().getState());
final AroundClosure ac = arcs.get().peek();
return ac.run(ac.getState());
}
}

Expand All @@ -177,7 +190,7 @@ public Object proceed(Object[] adviceBindings) throws Throwable {
if (arcs == null) {
ac = arc;
} else {
ac = arcs.peek();
ac = arcs.get().peek();
}

if (ac == null) {
Expand Down

0 comments on commit 3c80a36

Please sign in to comment.