@@ -120,8 +120,7 @@ public class JavaScriptEngine implements AbstractJavaScriptEngine<Script> {
120120 private JavaScriptConfiguration jsConfig_ ;
121121
122122 private transient ThreadLocal <Boolean > javaScriptRunning_ ;
123- private transient ThreadLocal <List <PostponedAction >> postponedActions_ ;
124- private transient ThreadLocal <RootPostponedActionsBlocker > postponedActionsBlocker_ ;
123+ private transient ThreadLocal <PostponedActionsManager > postponedActionsManager_ ;
125124 private transient boolean shutdownPending_ ;
126125
127126 /** The JavaScriptExecutor corresponding to all windows of this Web client */
@@ -696,15 +695,12 @@ public void shutdown() {
696695 javaScriptExecutor_ .shutdown ();
697696 javaScriptExecutor_ = null ;
698697 }
699- if (postponedActions_ != null ) {
700- postponedActions_ .remove ();
698+ if (postponedActionsManager_ != null ) {
699+ postponedActionsManager_ .remove ();
701700 }
702701 if (javaScriptRunning_ != null ) {
703702 javaScriptRunning_ .remove ();
704703 }
705- if (postponedActionsBlocker_ != null ) {
706- postponedActionsBlocker_ .remove ();
707- }
708704 }
709705
710706 /**
@@ -926,9 +922,7 @@ public final Object run(final Context cx) {
926922
927923 // doProcessPostponedActions is synchronized
928924 // moved out of the sync block to avoid deadlocks
929- if (postponedActionsBlocker_ == null ) {
930- doProcessPostponedActions ();
931- }
925+ doProcessPostponedActions ();
932926
933927 return response ;
934928 }
@@ -950,12 +944,27 @@ public final Object run(final Context cx) {
950944 protected abstract String getSourceCode (Context cx );
951945 }
952946
947+ private PostponedActionsManager getPostponedActionsManager () {
948+ PostponedActionsManager manager = postponedActionsManager_ .get ();
949+ if (manager != null ) {
950+ return manager ;
951+ }
952+
953+ manager = new PostponedActionsManager ();
954+ postponedActionsManager_ .set (manager );
955+ return manager ;
956+ }
957+
953958 private void doProcessPostponedActions () {
959+ final PostponedActionsManager postponedActionsManager = getPostponedActionsManager ();
960+ if (postponedActionsManager .postponedActionsBlocker_ != null ) {
961+ return ;
962+ }
963+
954964 final WebClient webClient = getWebClient ();
955965 if (webClient == null ) {
956966 // shutdown was already called
957- postponedActions_ .set (null );
958- postponedActionsBlocker_ .set (null );
967+ postponedActionsManager_ .remove ();
959968 return ;
960969 }
961970
@@ -969,11 +978,12 @@ private void doProcessPostponedActions() {
969978 throw new RuntimeException (e );
970979 }
971980
972- final List <PostponedAction > actions = postponedActions_ . get () ;
973- final PostponedActionsBlocker postponedActionsBlocker = postponedActionsBlocker_ . get () ;
981+ final List <PostponedAction > actions = postponedActionsManager . postponedActions_ ;
982+ final PostponedActionsBlocker postponedActionsBlocker = postponedActionsManager . postponedActionsBlocker_ ;
974983 if (actions != null ) {
975- postponedActions_ .set (null );
976984 try {
985+ postponedActionsManager .postponedActions_ = null ;
986+
977987 for (final PostponedAction action : actions ) {
978988 if (LOG .isDebugEnabled ()) {
979989 LOG .debug ("Processing PostponedAction " + action );
@@ -1009,12 +1019,7 @@ public void addPostponedAction(final PostponedAction action) {
10091019 return ;
10101020 }
10111021
1012- List <PostponedAction > actions = postponedActions_ .get ();
1013- if (actions == null ) {
1014- actions = new ArrayList <>();
1015- postponedActions_ .set (actions );
1016- }
1017- actions .add (action );
1022+ getPostponedActionsManager ().addPostponedAction (action );
10181023 }
10191024
10201025 /**
@@ -1026,7 +1031,8 @@ public boolean postponedActionPending() {
10261031 return false ;
10271032 }
10281033
1029- final List <PostponedAction > actions = postponedActions_ .get ();
1034+ final PostponedActionsManager postponedActionsManager = getPostponedActionsManager ();
1035+ final List <PostponedAction > actions = postponedActionsManager .postponedActions_ ;
10301036 return actions != null && actions .size () > 0 ;
10311037 }
10321038
@@ -1091,21 +1097,7 @@ protected void handleJavaScriptTimeoutError(final HtmlPage page, final TimeoutEr
10911097 */
10921098 @ Override
10931099 public PostponedActionsBlocker blockPostponedActions (final Page page ) {
1094- RootPostponedActionsBlocker blocker = postponedActionsBlocker_ .get ();
1095- if (blocker == null ) {
1096- blocker = new RootPostponedActionsBlocker (this , page );
1097- postponedActionsBlocker_ .set (blocker );
1098- return blocker ;
1099- }
1100-
1101- if (blocker .owningPage_ != page ) {
1102- blocker .release ();
1103- blocker = new RootPostponedActionsBlocker (this , page );
1104- postponedActionsBlocker_ .set (blocker );
1105- return blocker ;
1106- }
1107-
1108- return new ChildPostponedActionsBlocker (blocker );
1100+ return getPostponedActionsManager ().blockPostponedActions (this , page );
11091101 }
11101102
11111103 /**
@@ -1127,8 +1119,7 @@ private void readObject(final ObjectInputStream in) throws IOException, ClassNot
11271119
11281120 private void initTransientFields () {
11291121 javaScriptRunning_ = new ThreadLocal <>();
1130- postponedActions_ = new ThreadLocal <>();
1131- postponedActionsBlocker_ = new ThreadLocal <>();
1122+ postponedActionsManager_ = new ThreadLocal <>();
11321123 shutdownPending_ = false ;
11331124 }
11341125
@@ -1455,10 +1446,43 @@ public static String evaluateProxyAutoConfig(final BrowserVersion browserVersion
14551446 }
14561447 }
14571448
1449+ private static final class PostponedActionsManager {
1450+ private List <PostponedAction > postponedActions_ ;
1451+ private RootPostponedActionsBlocker postponedActionsBlocker_ ;
1452+
1453+ PostponedActionsManager () {
1454+ super ();
1455+ }
1456+
1457+ PostponedActionsBlocker blockPostponedActions (final JavaScriptEngine engine , final Page page ) {
1458+ if (postponedActionsBlocker_ == null ) {
1459+ postponedActionsBlocker_ = new RootPostponedActionsBlocker (engine , page );
1460+ return postponedActionsBlocker_ ;
1461+ }
1462+
1463+ if (postponedActionsBlocker_ .owningPage_ != page ) {
1464+ postponedActionsBlocker_ .release ();
1465+ postponedActionsBlocker_ = new RootPostponedActionsBlocker (engine , page );
1466+ return postponedActionsBlocker_ ;
1467+ }
1468+
1469+ return new ChildPostponedActionsBlocker (postponedActionsBlocker_ );
1470+ }
1471+
1472+ public void addPostponedAction (final PostponedAction action ) {
1473+ if (postponedActions_ == null ) {
1474+ postponedActions_ = new ArrayList <>();
1475+ postponedActions_ .add (action );
1476+ return ;
1477+ }
1478+ postponedActions_ .add (action );
1479+ }
1480+ }
1481+
14581482 /**
14591483 * {@link PostponedActionsBlocker} - the first requested in the current context.
14601484 */
1461- private final class RootPostponedActionsBlocker implements PostponedActionsBlocker {
1485+ private static final class RootPostponedActionsBlocker implements PostponedActionsBlocker {
14621486 private final JavaScriptEngine jsEngine_ ;
14631487 private final Page owningPage_ ;
14641488
@@ -1474,15 +1498,15 @@ public boolean blocks(final PostponedAction postponedAction) {
14741498
14751499 @ Override
14761500 public void release () {
1477- jsEngine_ .postponedActionsBlocker_ . set ( null ) ;
1501+ jsEngine_ .getPostponedActionsManager (). postponedActionsBlocker_ = null ;
14781502 jsEngine_ .processPostponedActions ();
14791503 }
14801504 }
14811505
14821506 /**
14831507 * {@link PostponedActionsBlocker} - noop blocker.
14841508 */
1485- private final class ChildPostponedActionsBlocker implements PostponedActionsBlocker {
1509+ private static final class ChildPostponedActionsBlocker implements PostponedActionsBlocker {
14861510 private final RootPostponedActionsBlocker root_ ;
14871511
14881512 private ChildPostponedActionsBlocker (final RootPostponedActionsBlocker root ) {
0 commit comments