{
startServer(null);
final long timeout = 2000;
final long sleep = 500;
JSONTransport transport = new JSONTransport(bayeux)
{
@Override
protected HttpScheduler newHttpScheduler(HttpServletRequest request, HttpServletResponse response, AsyncContext asyncContext, ServerSessionImpl session, ServerMessage.Mutable reply, String browserId, long timeout)
{
return new DispatchingLongPollScheduler(request, response, asyncContext, session, reply, browserId, timeout)
{
private final AtomicInteger decrements = new AtomicInteger();
@Override
public void onComplete(final AsyncEvent asyncEvent) throws IOException
{
if (decrements.incrementAndGet() == 1)
{
// Simulate that onComplete() is delayed without blocking
// this thread, to cause a race condition
new Thread()
{
@Override
public void run()
{
try
{
Thread.sleep(sleep);
superOnComplete(asyncEvent);
}
catch (Exception x)
{
x.printStackTrace();
}
}
}.start();
}
else
{
superOnComplete(asyncEvent);
}
}
private void superOnComplete(AsyncEvent asyncEvent) throws IOException
{
super.onComplete(asyncEvent);
}
};
}
};
transport.setOption(AbstractServerTransport.TIMEOUT_OPTION, timeout);
transport.init();
bayeux.setTransports(transport);
Request handshake = newBayeuxRequest("[{" +
"\"channel\": \"/meta/handshake\"," +
"\"version\": \"1.0\"," +