From d6aea8909bf7a210de447bce0deab5de981cddaf Mon Sep 17 00:00:00 2001 From: Jeanfrancois Arcand Date: Mon, 27 Aug 2012 14:38:11 -0700 Subject: [PATCH] Fix for #576 Possible Thread Race when Broadcaster gets destroyed and the re-use option is set to true --- .../org/atmosphere/cpr/AsynchronousProcessor.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/modules/cpr/src/main/java/org/atmosphere/cpr/AsynchronousProcessor.java b/modules/cpr/src/main/java/org/atmosphere/cpr/AsynchronousProcessor.java index 35c8d41d10d..37255a7c9f8 100755 --- a/modules/cpr/src/main/java/org/atmosphere/cpr/AsynchronousProcessor.java +++ b/modules/cpr/src/main/java/org/atmosphere/cpr/AsynchronousProcessor.java @@ -92,9 +92,11 @@ public abstract class AsynchronousProcessor implements AsyncSupport(); private boolean trackActiveRequest = false; private final ScheduledExecutorService closedDetector = Executors.newScheduledThreadPool(1); + private final BroadcasterFactory broadcasterFactory; public AsynchronousProcessor(AtmosphereConfig config) { this.config = config; + this.broadcasterFactory = config.getBroadcasterFactory(); } @Override @@ -207,9 +209,16 @@ Action action(AtmosphereRequest req, AtmosphereResponse res) throws IOException, // Check Broadcaster state. If destroyed, replace it. Broadcaster b = handlerWrapper.broadcaster; if (b.isDestroyed()) { - synchronized (handlerWrapper) { - config.getBroadcasterFactory().remove(b, b.getID()); - handlerWrapper.broadcaster = config.getBroadcasterFactory().get(b.getID()); + synchronized (broadcasterFactory) { + broadcasterFactory.remove(b, b.getID()); + try { + handlerWrapper.broadcaster = broadcasterFactory.get(b.getID()); + } catch (IllegalStateException ex) { + // Something wrong occurred, let's not fail and loookup the value + logger.trace("", ex); + // fallback to lookup + handlerWrapper.broadcaster = broadcasterFactory.lookup(b.getID(), true); + } } }