Commit efe7d498 authored by Tom Evans's avatar Tom Evans Committed by tevans

OF-573: Improve synchronization model for http-bind to reduce thread blocking;...

OF-573: Improve synchronization model for http-bind to reduce thread blocking; include static web context resources for http-bind in RPM build

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@13305 b35dd754-fafc-0310-a699-88a17e54d16e
parent 309ba9a6
...@@ -72,7 +72,6 @@ rm -rf $RPM_BUILD_ROOT%{homedir}/resources/nativeAuth/osx-ppc ...@@ -72,7 +72,6 @@ rm -rf $RPM_BUILD_ROOT%{homedir}/resources/nativeAuth/osx-ppc
rm -rf $RPM_BUILD_ROOT%{homedir}/resources/nativeAuth/solaris-sparc rm -rf $RPM_BUILD_ROOT%{homedir}/resources/nativeAuth/solaris-sparc
rm -rf $RPM_BUILD_ROOT%{homedir}/resources/nativeAuth/win32-x86 rm -rf $RPM_BUILD_ROOT%{homedir}/resources/nativeAuth/win32-x86
rm -f $RPM_BUILD_ROOT%{homedir}/lib/*.dll rm -f $RPM_BUILD_ROOT%{homedir}/lib/*.dll
rm -rf $RPM_BUILD_ROOT%{homedir}/resources/spank
%clean %clean
rm -rf $RPM_BUILD_ROOT rm -rf $RPM_BUILD_ROOT
...@@ -129,6 +128,10 @@ exit 0 ...@@ -129,6 +128,10 @@ exit 0
%dir %{homedir}/resources/nativeAuth/linux-i386 %dir %{homedir}/resources/nativeAuth/linux-i386
%{homedir}/resources/nativeAuth/linux-i386/* %{homedir}/resources/nativeAuth/linux-i386/*
%dir %{homedir}/resources/security %dir %{homedir}/resources/security
%dir %{homedir}/resources/spank
%{homedir}/resources/spank/index.html
%dir %{homedir}/resources/spank/WEB-INF
%{homedir}/resources/spank/WEB-INF/web.xml
%config(noreplace) %{homedir}/resources/security/keystore %config(noreplace) %{homedir}/resources/security/keystore
%config(noreplace) %{homedir}/resources/security/truststore %config(noreplace) %{homedir}/resources/security/truststore
%config(noreplace) %{homedir}/resources/security/client.truststore %config(noreplace) %{homedir}/resources/security/client.truststore
......
...@@ -69,6 +69,10 @@ public final class HttpBindManager { ...@@ -69,6 +69,10 @@ public final class HttpBindManager {
public static final int HTTP_BIND_SECURE_PORT_DEFAULT = 7443; public static final int HTTP_BIND_SECURE_PORT_DEFAULT = 7443;
public static final String HTTP_BIND_THREADS = "httpbind.client.processing.threads";
public static final int HTTP_BIND_THREADS_DEFAULT = 254;
// http binding CORS default properties // http binding CORS default properties
public static final String HTTP_BIND_CORS_ENABLED = "httpbind.CORS.enabled"; public static final String HTTP_BIND_CORS_ENABLED = "httpbind.CORS.enabled";
...@@ -378,7 +382,8 @@ public final class HttpBindManager { ...@@ -378,7 +382,8 @@ public final class HttpBindManager {
*/ */
private synchronized void configureHttpBindServer(int port, int securePort) { private synchronized void configureHttpBindServer(int port, int securePort) {
httpBindServer = new Server(); httpBindServer = new Server();
final QueuedThreadPool tp = new QueuedThreadPool(254); final QueuedThreadPool tp = new QueuedThreadPool(
JiveGlobals.getIntProperty(HTTP_BIND_THREADS, HTTP_BIND_THREADS_DEFAULT));
tp.setName("Jetty-QTP-BOSH"); tp.setName("Jetty-QTP-BOSH");
httpBindServer.setThreadPool(tp); httpBindServer.setThreadPool(tp);
......
...@@ -29,7 +29,7 @@ import java.security.cert.X509Certificate; ...@@ -29,7 +29,7 @@ import java.security.cert.X509Certificate;
/** /**
* Represents one HTTP connection with a client using the HTTP Binding service. The client will wait * Represents one HTTP connection with a client using the HTTP Binding service. The client will wait
* on {@link #getResponse()} until the server forwards a message to it or the wait time on the * on {@link #getResponse()} until the server forwards a message to it or the wait time on the
* session timesout. * session timeout.
* *
* @author Alexander Wenckus * @author Alexander Wenckus
*/ */
...@@ -79,7 +79,7 @@ public class HttpConnection { ...@@ -79,7 +79,7 @@ public class HttpConnection {
/** /**
* Returns true if this connection has been closed, either a response was delivered to the * Returns true if this connection has been closed, either a response was delivered to the
* client or the server closed the connection abrubtly. * client or the server closed the connection abruptly.
* *
* @return true if this connection has been closed. * @return true if this connection has been closed.
*/ */
...@@ -107,14 +107,12 @@ public class HttpConnection { ...@@ -107,14 +107,12 @@ public class HttpConnection {
* *
* @param body the XMPP content to be forwarded to the client inside of a body tag. * @param body the XMPP content to be forwarded to the client inside of a body tag.
* *
* @throws HttpConnectionClosedException when this connection to the client has already recieved * @throws HttpConnectionClosedException when this connection to the client has already received
* a deliverable to forward to the client * a deliverable to forward to the client
*/ */
public void deliverBody(String body) throws HttpConnectionClosedException { public void deliverBody(String body) throws HttpConnectionClosedException {
if(body == null) {
throw new IllegalArgumentException("Body cannot be null!");
}
// We only want to use this function once so we will close it when the body is delivered. // We only want to use this function once so we will close it when the body is delivered.
synchronized (this) {
if (isClosed) { if (isClosed) {
throw new HttpConnectionClosedException("The http connection is no longer " + throw new HttpConnectionClosedException("The http connection is no longer " +
"available to deliver content"); "available to deliver content");
...@@ -122,7 +120,10 @@ public class HttpConnection { ...@@ -122,7 +120,10 @@ public class HttpConnection {
else { else {
isClosed = true; isClosed = true;
} }
}
if (body == null) {
body = CONNECTION_CLOSED;
}
if (continuation != null && continuation.isSuspended()) { if (continuation != null && continuation.isSuspended()) {
continuation.setAttribute("response-body", body); continuation.setAttribute("response-body", body);
continuation.resume(); continuation.resume();
...@@ -212,7 +213,7 @@ public class HttpConnection { ...@@ -212,7 +213,7 @@ public class HttpConnection {
if (continuation.isResumed()) { if (continuation.isResumed()) {
String deliverable = (String) continuation.getAttribute("response-body"); String deliverable = (String) continuation.getAttribute("response-body");
// This will occur when the hold attribute of a session has been exceded. // This will occur when the hold attribute of a session has been exceeded.
this.isDelivered = true; this.isDelivered = true;
if (deliverable == null) { if (deliverable == null) {
throw new HttpBindTimeoutException(); throw new HttpBindTimeoutException();
......
...@@ -99,9 +99,9 @@ public class HttpSession extends LocalClientSession { ...@@ -99,9 +99,9 @@ public class HttpSession extends LocalClientSession {
private int wait; private int wait;
private int hold = 0; private int hold = 0;
private String language; private String language;
private final List<HttpConnection> connectionQueue = new LinkedList<HttpConnection>(); private final List<HttpConnection> connectionQueue = Collections.synchronizedList(new LinkedList<HttpConnection>());
private final List<Deliverable> pendingElements = new ArrayList<Deliverable>(); private final List<Deliverable> pendingElements = Collections.synchronizedList(new ArrayList<Deliverable>());
private final List<Delivered> sentElements = new ArrayList<Delivered>(); private final List<Delivered> sentElements = Collections.synchronizedList(new ArrayList<Delivered>());
private boolean isSecure; private boolean isSecure;
private int maxPollingInterval; private int maxPollingInterval;
private long lastPoll = -1; private long lastPoll = -1;
...@@ -134,6 +134,7 @@ public class HttpSession extends LocalClientSession { ...@@ -134,6 +134,7 @@ public class HttpSession extends LocalClientSession {
StreamID streamID, long rid, HttpConnection connection) { StreamID streamID, long rid, HttpConnection connection) {
super(serverName, null, streamID); super(serverName, null, streamID);
conn = new HttpVirtualConnection(address); conn = new HttpVirtualConnection(address);
this.isClosed = false;
this.lastActivity = System.currentTimeMillis(); this.lastActivity = System.currentTimeMillis();
this.lastRequestID = rid; this.lastRequestID = rid;
this.backupDeliverer = backupDeliverer; this.backupDeliverer = backupDeliverer;
...@@ -197,12 +198,12 @@ public class HttpSession extends LocalClientSession { ...@@ -197,12 +198,12 @@ public class HttpSession extends LocalClientSession {
} }
/** /**
* Returns true if this session has been closed and no longer activley accepting connections. * Returns true if this session has been closed and no longer actively accepting connections.
* *
* @return true if this session has been closed and no longer activley accepting connections. * @return true if this session has been closed and no longer actively accepting connections.
*/ */
@Override @Override
public synchronized boolean isClosed() { public boolean isClosed() {
return isClosed; return isClosed;
} }
...@@ -295,9 +296,9 @@ public class HttpSession extends LocalClientSession { ...@@ -295,9 +296,9 @@ public class HttpSession extends LocalClientSession {
} }
/** /**
* The max number of requests it is permissable for this session to have open at any one time. * The max number of requests it is permissible for this session to have open at any one time.
* *
* @param maxRequests The max number of requests it is permissable for this session to have open * @param maxRequests The max number of requests it is permissible for this session to have open
* at any one time. * at any one time.
*/ */
public void setMaxRequests(int maxRequests) { public void setMaxRequests(int maxRequests) {
...@@ -305,10 +306,10 @@ public class HttpSession extends LocalClientSession { ...@@ -305,10 +306,10 @@ public class HttpSession extends LocalClientSession {
} }
/** /**
* Returns the max number of requests it is permissable for this session to have open at any one * Returns the max number of requests it is permissible for this session to have open at any one
* time. * time.
* *
* @return the max number of requests it is permissable for this session to have open at any one * @return the max number of requests it is permissible for this session to have open at any one
* time. * time.
*/ */
public int getMaxRequests() { public int getMaxRequests() {
...@@ -438,12 +439,14 @@ public class HttpSession extends LocalClientSession { ...@@ -438,12 +439,14 @@ public class HttpSession extends LocalClientSession {
*/ */
public void pause(int duration) { public void pause(int duration) {
// Respond immediately to all pending requests // Respond immediately to all pending requests
synchronized (connectionQueue) {
for (HttpConnection toClose : connectionQueue) { for (HttpConnection toClose : connectionQueue) {
if (!toClose.isClosed()) { if (!toClose.isClosed()) {
toClose.close(); toClose.close();
lastRequestID = toClose.getRequestId(); lastRequestID = toClose.getRequestId();
} }
} }
}
setInactivityTimeout(duration); setInactivityTimeout(duration);
} }
...@@ -454,22 +457,20 @@ public class HttpSession extends LocalClientSession { ...@@ -454,22 +457,20 @@ public class HttpSession extends LocalClientSession {
* *
* @return the time in milliseconds since the epoch that this session was last active. * @return the time in milliseconds since the epoch that this session was last active.
*/ */
public synchronized long getLastActivity() { public long getLastActivity() {
if (connectionQueue.isEmpty()) { if (!connectionQueue.isEmpty()) {
return lastActivity; synchronized (connectionQueue) {
}
else {
for (HttpConnection connection : connectionQueue) { for (HttpConnection connection : connectionQueue) {
// The session is currently active, return the current time. // The session is currently active, set the last activity to the current time.
if (!connection.isClosed()) { if (!connection.isClosed()) {
return System.currentTimeMillis(); lastActivity = System.currentTimeMillis();
break;
} }
} }
// We have no currently open connections therefore we can assume that lastActivity is
// the last time the client did anything.
return lastActivity;
} }
} }
return lastActivity;
}
/** /**
* Returns the highest 'rid' attribute the server has received where it has also received * Returns the highest 'rid' attribute the server has received where it has also received
...@@ -484,11 +485,13 @@ public class HttpSession extends LocalClientSession { ...@@ -484,11 +485,13 @@ public class HttpSession extends LocalClientSession {
public long getLastAcknowledged() { public long getLastAcknowledged() {
long ack = lastRequestID; long ack = lastRequestID;
Collections.sort(connectionQueue, connectionComparator); Collections.sort(connectionQueue, connectionComparator);
synchronized (connectionQueue) {
for (HttpConnection connection : connectionQueue) { for (HttpConnection connection : connectionQueue) {
if (connection.getRequestId() == ack + 1) { if (connection.getRequestId() == ack + 1) {
ack++; ack++;
} }
} }
}
return ack; return ack;
} }
...@@ -572,6 +575,7 @@ public class HttpSession extends LocalClientSession { ...@@ -572,6 +575,7 @@ public class HttpSession extends LocalClientSession {
* Use {@link #consumeResponse(HttpConnection)} instead * Use {@link #consumeResponse(HttpConnection)} instead
*/ */
public String getResponse(long requestID) throws HttpBindException { public String getResponse(long requestID) throws HttpBindException {
synchronized (connectionQueue) {
for (HttpConnection connection : connectionQueue) { for (HttpConnection connection : connectionQueue) {
if (connection.getRequestId() == requestID) { if (connection.getRequestId() == requestID) {
String response = getResponse(connection); String response = getResponse(connection);
...@@ -584,6 +588,7 @@ public class HttpSession extends LocalClientSession { ...@@ -584,6 +588,7 @@ public class HttpSession extends LocalClientSession {
return response; return response;
} }
} }
}
throw new InternalError("Could not locate connection: " + requestID); throw new InternalError("Could not locate connection: " + requestID);
} }
...@@ -641,8 +646,8 @@ public class HttpSession extends LocalClientSession { ...@@ -641,8 +646,8 @@ public class HttpSession extends LocalClientSession {
/** /**
* This methods sends any pending packets in the session. If no packets are * This methods sends any pending packets in the session. If no packets are
* pending, this method simply returns. The method is internally synchronized * pending, this method simply returns. The method is internally synchronized
* to avoid simultanious sending operations on this Session. If two * to avoid simultaneous sending operations on this Session. If two
* threads try to run this method simultaniously, the first one will trigger * threads try to run this method simultaneously, the first one will trigger
* the pending packets to be sent, while the second one will simply return * the pending packets to be sent, while the second one will simply return
* (as there are no packets left to send). * (as there are no packets left to send).
*/ */
...@@ -728,12 +733,16 @@ public class HttpSession extends LocalClientSession { ...@@ -728,12 +733,16 @@ public class HttpSession extends LocalClientSession {
} }
private Delivered retrieveDeliverable(long rid) { private Delivered retrieveDeliverable(long rid) {
Delivered result = null;
synchronized (sentElements) {
for (Delivered delivered : sentElements) { for (Delivered delivered : sentElements) {
if (delivered.getRequestID() == rid) { if (delivered.getRequestID() == rid) {
return delivered; result = delivered;
break;
} }
} }
return null; }
return result;
} }
private void addConnection(HttpConnection connection, boolean isPoll) throws HttpBindException, private void addConnection(HttpConnection connection, boolean isPoll) throws HttpBindException,
...@@ -755,6 +764,7 @@ public class HttpSession extends LocalClientSession { ...@@ -755,6 +764,7 @@ public class HttpSession extends LocalClientSession {
* deliverable on the new connection. This is under the assumption that a connection has been dropped, * deliverable on the new connection. This is under the assumption that a connection has been dropped,
* and re-requested before jetty has realised. * and re-requested before jetty has realised.
*/ */
synchronized (connectionQueue) {
for (HttpConnection queuedConnection : connectionQueue) { for (HttpConnection queuedConnection : connectionQueue) {
if (queuedConnection.getRequestId() == rid) { if (queuedConnection.getRequestId() == rid) {
if(Log.isDebugEnabled()) { if(Log.isDebugEnabled()) {
...@@ -786,6 +796,7 @@ public class HttpSession extends LocalClientSession { ...@@ -786,6 +796,7 @@ public class HttpSession extends LocalClientSession {
break; break;
} }
} }
}
checkOveractivity(isPoll); checkOveractivity(isPoll);
...@@ -808,6 +819,7 @@ public class HttpSession extends LocalClientSession { ...@@ -808,6 +819,7 @@ public class HttpSession extends LocalClientSession {
connectionQueue.add(connection); connectionQueue.add(connection);
Collections.sort(connectionQueue, connectionComparator); Collections.sort(connectionQueue, connectionComparator);
synchronized (connectionQueue) {
int connectionsToClose; int connectionsToClose;
if(connectionQueue.get(connectionQueue.size() - 1) != connection) { if(connectionQueue.get(connectionQueue.size() - 1) != connection) {
// Current connection does not have the greatest rid. That means // Current connection does not have the greatest rid. That means
...@@ -835,11 +847,13 @@ public class HttpSession extends LocalClientSession { ...@@ -835,11 +847,13 @@ public class HttpSession extends LocalClientSession {
} }
} }
} }
}
fireConnectionOpened(connection); fireConnectionOpened(connection);
} }
private int getOpenConnectionCount() { private int getOpenConnectionCount() {
int count = 0; int count = 0;
// NOTE: synchronized by caller
for (HttpConnection connection : connectionQueue) { for (HttpConnection connection : connectionQueue) {
if (!connection.isClosed()) { if (!connection.isClosed()) {
count++; count++;
...@@ -883,11 +897,13 @@ public class HttpSession extends LocalClientSession { ...@@ -883,11 +897,13 @@ public class HttpSession extends LocalClientSession {
boolean overactivity = false; boolean overactivity = false;
String errorMessage = "Overactivity detected"; String errorMessage = "Overactivity detected";
synchronized (connectionQueue) {
for (HttpConnection conn : connectionQueue) { for (HttpConnection conn : connectionQueue) {
if (!conn.isClosed()) { if (!conn.isClosed()) {
pendingConnections++; pendingConnections++;
} }
} }
}
if(pendingConnections >= maxRequests) { if(pendingConnections >= maxRequests) {
overactivity = true; overactivity = true;
...@@ -917,7 +933,7 @@ public class HttpSession extends LocalClientSession { ...@@ -917,7 +933,7 @@ public class HttpSession extends LocalClientSession {
} }
} }
private synchronized void deliver(String text) { private void deliver(String text) {
if (text == null) { if (text == null) {
// Do nothing if someone asked to send nothing :) // Do nothing if someone asked to send nothing :)
return; return;
...@@ -925,13 +941,14 @@ public class HttpSession extends LocalClientSession { ...@@ -925,13 +941,14 @@ public class HttpSession extends LocalClientSession {
deliver(new Deliverable(text)); deliver(new Deliverable(text));
} }
private synchronized void deliver(Packet stanza) { public void deliver(Packet stanza) {
deliver(new Deliverable(Arrays.asList(stanza))); deliver(new Deliverable(Arrays.asList(stanza)));
} }
private void deliver(Deliverable stanza) { private void deliver(Deliverable stanza) {
Collection<Deliverable> deliverable = Arrays.asList(stanza); Collection<Deliverable> deliverable = Arrays.asList(stanza);
boolean delivered = false; boolean delivered = false;
synchronized (connectionQueue) {
for (HttpConnection connection : connectionQueue) { for (HttpConnection connection : connectionQueue) {
try { try {
if (connection.getRequestId() == lastRequestID + 1) { if (connection.getRequestId() == lastRequestID + 1) {
...@@ -945,6 +962,7 @@ public class HttpSession extends LocalClientSession { ...@@ -945,6 +962,7 @@ public class HttpSession extends LocalClientSession {
/* Connection was closed, try the next one */ /* Connection was closed, try the next one */
} }
} }
}
if (!delivered) { if (!delivered) {
pendingElements.add(stanza); pendingElements.add(stanza);
...@@ -969,18 +987,20 @@ public class HttpSession extends LocalClientSession { ...@@ -969,18 +987,20 @@ public class HttpSession extends LocalClientSession {
builder.append(">"); builder.append(">");
setLastResponseEmpty(elements.size() == 0); setLastResponseEmpty(elements.size() == 0);
synchronized (elements) {
for (Deliverable child : elements) { for (Deliverable child : elements) {
builder.append(child.getDeliverable()); builder.append(child.getDeliverable());
} }
}
builder.append("</body>"); builder.append("</body>");
return builder.toString(); return builder.toString();
} }
private synchronized void closeConnection() { private void closeSession() {
if (isClosed) { synchronized (this) {
return; if (isClosed) { return; }
}
isClosed = true; isClosed = true;
}
if (pendingElements.size() > 0) { if (pendingElements.size() > 0) {
failDelivery(); failDelivery();
...@@ -993,13 +1013,17 @@ public class HttpSession extends LocalClientSession { ...@@ -993,13 +1013,17 @@ public class HttpSession extends LocalClientSession {
} }
private void failDelivery() { private void failDelivery() {
synchronized (pendingElements) {
for (Deliverable deliverable : pendingElements) { for (Deliverable deliverable : pendingElements) {
Collection<Packet> packet = deliverable.getPackets(); Collection<Packet> packet = deliverable.getPackets();
if (packet != null) { if (packet != null) {
failDelivery(packet); failDelivery(packet);
} }
} }
pendingElements.clear();
}
synchronized (connectionQueue) {
for (HttpConnection toClose : connectionQueue) { for (HttpConnection toClose : connectionQueue) {
if (!toClose.isDelivered()) { if (!toClose.isDelivered()) {
Delivered delivered = retrieveDeliverable(toClose.getRequestId()); Delivered delivered = retrieveDeliverable(toClose.getRequestId());
...@@ -1014,7 +1038,7 @@ public class HttpSession extends LocalClientSession { ...@@ -1014,7 +1038,7 @@ public class HttpSession extends LocalClientSession {
toClose.close(); toClose.close();
fireConnectionClosed(toClose); fireConnectionClosed(toClose);
} }
pendingElements.clear(); }
} }
private void failDelivery(Collection<Packet> packets) { private void failDelivery(Collection<Packet> packets) {
...@@ -1056,7 +1080,7 @@ public class HttpSession extends LocalClientSession { ...@@ -1056,7 +1080,7 @@ public class HttpSession extends LocalClientSession {
@Override @Override
public void closeVirtualConnection() { public void closeVirtualConnection() {
((HttpSession) session).closeConnection(); ((HttpSession) session).closeSession();
} }
public byte[] getAddress() throws UnknownHostException { public byte[] getAddress() throws UnknownHostException {
...@@ -1204,11 +1228,13 @@ public class HttpSession extends LocalClientSession { ...@@ -1204,11 +1228,13 @@ public class HttpSession extends LocalClientSession {
public Collection<Packet> getPackets() { public Collection<Packet> getPackets() {
List<Packet> packets = new ArrayList<Packet>(); List<Packet> packets = new ArrayList<Packet>();
synchronized (deliverables) {
for (Deliverable deliverable : deliverables) { for (Deliverable deliverable : deliverables) {
if (deliverable.packets != null) { if (deliverable.packets != null) {
packets.addAll(deliverable.getPackets()); packets.addAll(deliverable.getPackets());
} }
} }
}
return packets; return packets;
} }
} }
......
...@@ -51,7 +51,8 @@ public class HttpSessionManager { ...@@ -51,7 +51,8 @@ public class HttpSessionManager {
private static final Logger Log = LoggerFactory.getLogger(HttpSessionManager.class); private static final Logger Log = LoggerFactory.getLogger(HttpSessionManager.class);
private SessionManager sessionManager; private SessionManager sessionManager;
private Map<String, HttpSession> sessionMap = new ConcurrentHashMap<String, HttpSession>(); private Map<String, HttpSession> sessionMap = new ConcurrentHashMap<String, HttpSession>(
JiveGlobals.getIntProperty("xmpp.httpbind.session.initial.count", 16));
private TimerTask inactivityTask; private TimerTask inactivityTask;
private Executor sendPacketPool; private Executor sendPacketPool;
private SessionListener sessionListener = new SessionListener() { private SessionListener sessionListener = new SessionListener() {
...@@ -73,7 +74,8 @@ public class HttpSessionManager { ...@@ -73,7 +74,8 @@ public class HttpSessionManager {
this.sessionManager = SessionManager.getInstance(); this.sessionManager = SessionManager.getInstance();
// Set the executor to use for processing http requests // Set the executor to use for processing http requests
int eventThreads = JiveGlobals.getIntProperty("xmpp.client.processing.threads", 16); int eventThreads = JiveGlobals.getIntProperty("httpbind.client.processing.threads",
JiveGlobals.getIntProperty("xmpp.client.processing.threads", 16));
sendPacketPool = new ThreadPoolExecutor( sendPacketPool = new ThreadPoolExecutor(
eventThreads + 1, eventThreads + 1, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>() ); eventThreads + 1, eventThreads + 1, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>() );
} }
......
...@@ -838,7 +838,7 @@ public class LocalClientSession extends LocalSession implements ClientSession { ...@@ -838,7 +838,7 @@ public class LocalClientSession extends LocalSession implements ClientSession {
} }
@Override @Override
void deliver(Packet packet) throws UnauthorizedException { public void deliver(Packet packet) throws UnauthorizedException {
if (conn != null && !conn.isClosed()) { if (conn != null && !conn.isClosed()) {
conn.deliver(packet); conn.deliver(packet);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment