Merge branch 'jetty-9.4.x-3361-thread-safe-setHandlers' of github.com:eclipse/jetty.project into jetty-9.4.x-3361-thread-safe-setHandlers
This commit is contained in:
commit
2f2c9f2f3f
|
@ -43,8 +43,7 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
import org.eclipse.jetty.util.thread.SerializedExecutor;
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** ContextHandlerCollection.
|
||||
*
|
||||
/**
|
||||
* This {@link org.eclipse.jetty.server.handler.HandlerCollection} is creates a
|
||||
* Map of contexts to it's contained handlers based
|
||||
* on the context path and virtual hosts of any contained {@link org.eclipse.jetty.server.handler.ContextHandler}s.
|
||||
|
@ -87,10 +86,8 @@ public class ContextHandlerCollection extends HandlerCollection
|
|||
protected Handlers newHandlers(Handler[] handlers)
|
||||
{
|
||||
if (handlers==null || handlers.length==0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// Create map of contextPath to handler Branch
|
||||
// A branch is a Handler that could contain 0 or more ContextHandlers
|
||||
Map<String,Branch[]> path2Branches = new HashMap<>();
|
||||
|
@ -133,7 +130,7 @@ public class ContextHandlerCollection extends HandlerCollection
|
|||
continue loop;
|
||||
}
|
||||
}
|
||||
break loop;
|
||||
break;
|
||||
}
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
|
@ -156,9 +153,6 @@ public class ContextHandlerCollection extends HandlerCollection
|
|||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/*
|
||||
* @see org.eclipse.jetty.server.server.Handler#handle(java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
|
||||
*/
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
|
@ -167,9 +161,6 @@ public class ContextHandlerCollection extends HandlerCollection
|
|||
return;
|
||||
|
||||
Mapping mapping = (Mapping)handlers;
|
||||
if (mapping==null)
|
||||
return;
|
||||
|
||||
HttpChannelState async = baseRequest.getHttpChannelState();
|
||||
if (async.isAsync())
|
||||
{
|
||||
|
@ -230,7 +221,9 @@ public class ContextHandlerCollection extends HandlerCollection
|
|||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/** Add a context handler.
|
||||
/**
|
||||
* Adds a context handler.
|
||||
*
|
||||
* @param contextPath The context path to add
|
||||
* @param resourceBase the base (root) Resource
|
||||
* @return the ContextHandler just added
|
||||
|
@ -273,7 +266,6 @@ public class ContextHandlerCollection extends HandlerCollection
|
|||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void undeployHandler(Handler handler)
|
||||
/**
|
||||
* Thread safe undeploy of a Handler.
|
||||
* <p>
|
||||
|
@ -285,6 +277,7 @@ public class ContextHandlerCollection extends HandlerCollection
|
|||
* </p>
|
||||
* @param handler The handler to undeploy
|
||||
*/
|
||||
public void undeployHandler(Handler handler)
|
||||
{
|
||||
_serializedExecutor.execute(()-> removeHandler(handler));
|
||||
}
|
||||
|
@ -298,7 +291,6 @@ public class ContextHandlerCollection extends HandlerCollection
|
|||
return _contextClass;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param contextClass The class to use to add new Contexts
|
||||
|
@ -338,7 +330,7 @@ public class ContextHandlerCollection extends HandlerCollection
|
|||
|
||||
Set<String> getContextPaths()
|
||||
{
|
||||
Set<String> set = new HashSet<String>();
|
||||
Set<String> set = new HashSet<>();
|
||||
for (ContextHandler context:_contexts)
|
||||
set.add(context.getContextPath());
|
||||
return set;
|
||||
|
@ -380,7 +372,7 @@ public class ContextHandlerCollection extends HandlerCollection
|
|||
Mapping(Handler[] handlers, int capacity)
|
||||
{
|
||||
super(handlers);
|
||||
_pathBranches = new ArrayTernaryTrie(false, capacity);
|
||||
_pathBranches = new ArrayTernaryTrie<>(false, capacity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ public class HandlerCollection extends AbstractHandlerContainer
|
|||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return Returns the handlers.
|
||||
* @return the array of handlers.
|
||||
*/
|
||||
@Override
|
||||
@ManagedAttribute(value="Wrapped handlers", readonly=true)
|
||||
|
@ -84,7 +84,7 @@ public class HandlerCollection extends AbstractHandlerContainer
|
|||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param handlers The handlers to set.
|
||||
* @param handlers the array of handlers to set.
|
||||
*/
|
||||
public void setHandlers(Handler[] handlers)
|
||||
{
|
||||
|
@ -93,9 +93,9 @@ public class HandlerCollection extends AbstractHandlerContainer
|
|||
|
||||
while(true)
|
||||
{
|
||||
if(updateHandlers(_handlers.get(),newHandlers(handlers)))
|
||||
if (updateHandlers(_handlers.get(), newHandlers(handlers)))
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -123,10 +123,11 @@ public class HandlerCollection extends AbstractHandlerContainer
|
|||
handler.setServer(getServer());
|
||||
}
|
||||
|
||||
|
||||
if (_handlers.compareAndSet(old,handlers))
|
||||
if (_handlers.compareAndSet(old, handlers))
|
||||
{
|
||||
updateBeans(old==null?null:old._handlers,handlers==null?null:handlers._handlers);
|
||||
Handler[] oldBeans = old == null ? null : old._handlers;
|
||||
Handler[] newBeans = handlers == null ? null : handlers._handlers;
|
||||
updateBeans(oldBeans, newBeans);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -143,28 +144,21 @@ public class HandlerCollection extends AbstractHandlerContainer
|
|||
if (handlers==null)
|
||||
return;
|
||||
|
||||
Handler[] h = handlers._handlers;
|
||||
|
||||
MultiException mex=null;
|
||||
|
||||
for (int i=0;i<h.length;i++)
|
||||
for (Handler handler : handlers._handlers)
|
||||
{
|
||||
try
|
||||
{
|
||||
h[i].handle(target,baseRequest, request, response);
|
||||
handler.handle(target, baseRequest, request, response);
|
||||
}
|
||||
catch(IOException e)
|
||||
catch (IOException | RuntimeException e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
catch(RuntimeException e)
|
||||
catch (Exception e)
|
||||
{
|
||||
throw e;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
if (mex==null)
|
||||
mex=new MultiException();
|
||||
if (mex == null)
|
||||
mex = new MultiException();
|
||||
mex.add(e);
|
||||
}
|
||||
}
|
||||
|
@ -179,9 +173,9 @@ public class HandlerCollection extends AbstractHandlerContainer
|
|||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* Add a handler.
|
||||
/**
|
||||
* Adds a handler.
|
||||
* This implementation adds the passed handler to the end of the existing collection of handlers.
|
||||
* @see org.eclipse.jetty.server.server.HandlerContainer#addHandler(org.eclipse.jetty.server.server.Handler)
|
||||
*/
|
||||
public void addHandler(Handler handler)
|
||||
{
|
||||
|
@ -195,9 +189,9 @@ public class HandlerCollection extends AbstractHandlerContainer
|
|||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* Prepend a handler.
|
||||
/**
|
||||
* Prepends a handler.
|
||||
* This implementation adds the passed handler to the start of the existing collection of handlers.
|
||||
* @see org.eclipse.jetty.server.server.HandlerContainer#addHandler(org.eclipse.jetty.server.server.Handler)
|
||||
*/
|
||||
public void prependHandler(Handler handler)
|
||||
{
|
||||
|
@ -216,7 +210,6 @@ public class HandlerCollection extends AbstractHandlerContainer
|
|||
while(true)
|
||||
{
|
||||
Handlers old = _handlers.get();
|
||||
|
||||
if (old==null || old._handlers.length==0)
|
||||
break;
|
||||
Handlers handlers = newHandlers(ArrayUtil.removeFromArray(old._handlers, handler));
|
||||
|
|
|
@ -30,9 +30,8 @@ import org.junit.jupiter.api.Test;
|
|||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class SerializedExecutorTest
|
||||
public class SerializedExecutorTest
|
||||
{
|
||||
|
||||
@Test
|
||||
public void test() throws Exception
|
||||
{
|
||||
|
@ -43,19 +42,19 @@ class SerializedExecutorTest
|
|||
AtomicInteger ran = new AtomicInteger();
|
||||
AtomicBoolean running = new AtomicBoolean();
|
||||
SerializedExecutor executor = new SerializedExecutor();
|
||||
final CountDownLatch start = new CountDownLatch(1);
|
||||
final CountDownLatch stop = new CountDownLatch(threads);
|
||||
final Random random = new Random();
|
||||
CountDownLatch start = new CountDownLatch(1);
|
||||
CountDownLatch stop = new CountDownLatch(threads);
|
||||
Random random = new Random();
|
||||
|
||||
for (int t=threads; t-->0;)
|
||||
for (int t = threads; t-- > 0; )
|
||||
{
|
||||
new Thread(()->
|
||||
new Thread(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
start.await();
|
||||
|
||||
for (int l=loops; l-->0;)
|
||||
for (int l = loops; l-- > 0; )
|
||||
{
|
||||
final AtomicInteger d = new AtomicInteger(depth);
|
||||
executor.execute(new Runnable()
|
||||
|
@ -75,7 +74,7 @@ class SerializedExecutorTest
|
|||
Thread.sleep(random.nextInt(5));
|
||||
}
|
||||
}
|
||||
catch(Throwable th)
|
||||
catch (Throwable th)
|
||||
{
|
||||
th.printStackTrace();
|
||||
}
|
||||
|
@ -88,8 +87,6 @@ class SerializedExecutorTest
|
|||
|
||||
start.countDown();
|
||||
assertTrue(stop.await(30, TimeUnit.SECONDS));
|
||||
assertThat(ran.get(), Matchers.is(threads*loops*depth));
|
||||
assertThat(ran.get(), Matchers.is(threads * loops * depth));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue