setState(LifecycleState.STOPPING);
+ try {
+ protocolHandler.stop();
+ } catch (Exception e) {
+ throw new LifecycleException
+ (sm.getString
+ ("coyoteConnector.protocolHandlerStopFailed", e));
+ }
+
// MapperListener doesn't follow Lifecycle conventions
mapperListener.destroy();
}
/**
* Retrieves executor by name, null if not found
- * @param name String
+ * @param executorName String
* @return Executor
*/
- public Executor getExecutor(String name) {
+ public Executor getExecutor(String executorName) {
synchronized (executors) {
for (Executor executor: executors) {
- if (name.equals(executor.getName()))
+ if (executorName.equals(executor.getName()))
return executor;
}
}
@Override
protected void stopInternal() throws LifecycleException {
- // Stop our defined Connectors first
+ // Pause connectors first
synchronized (connectors) {
for (Connector connector: connectors) {
try {
}
}
- // Heuristic: Sleep for a while to ensure pause of the connector
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- // Ignore
- }
-
if(log.isInfoEnabled())
log.info(sm.getString("standardService.stop.name", this.name));
setState(LifecycleState.STOPPING);
container.stop();
}
}
- // FIXME pero -- Why container stop first? KeepAlive connections can send request!
- // Stop our defined Connectors first
+
+ // Now stop the connectors
synchronized (connectors) {
for (Connector connector: connectors) {
- if (LifecycleState.INITIALIZED.equals(
+ if (!LifecycleState.STARTED.equals(
connector.getState())) {
- // If Service fails to start, connectors may not have been
- // started
+ // Connectors only need stopping if they are currently
+ // started. They may have failed to start or may have been
+ // stopped (e.g. via a JMX call)
continue;
}
try {
/**
+ * Stop the protocol.
+ */
+ public void stop() throws Exception;
+
+
+ /**
* Destroy the protocol (optional).
*/
public void destroy() throws Exception;
boolean openSocket = true;
boolean keptAlive = false;
- while (started && !error) {
+ while (started && !error && !endpoint.isPaused()) {
// Parsing the request header
try {
}
// Add the socket to the poller
- if (!error) {
+ if (!error && !endpoint.isPaused()) {
endpoint.getPoller().add(socket);
} else {
openSocket = false;
}
rp.setStage(org.apache.coyote.Constants.STAGE_ENDED);
- if (!async || error)
+ if (!async || error || endpoint.isPaused())
recycle();
return openSocket;
log.info(sm.getString("ajpprotocol.resume", getName()));
}
- public void destroy() throws Exception {
+ public void stop() throws Exception {
+ try {
+ endpoint.stop();
+ } catch (Exception ex) {
+ log.error(sm.getString("ajpprotocol.endpoint.stoperror"), ex);
+ throw ex;
+ }
if (log.isInfoEnabled())
log.info(sm.getString("ajpprotocol.stop", getName()));
+ }
+
+ public void destroy() throws Exception {
+ if (log.isInfoEnabled())
+ log.info(sm.getString("ajpprotocol.destroy", getName()));
endpoint.destroy();
if (tpOname!=null)
Registry.getRegistry(null, null).unregisterComponent(tpOname);
// Error flag
error = false;
- while (started && !error) {
+ while (started && !error && !endpoint.isPaused()) {
// Parsing the request header
try {
recycle();
}
- if (async && !error) {
+ if (async && !error && !endpoint.isPaused()) {
rp.setStage(org.apache.coyote.Constants.STAGE_ENDED);
return SocketState.LONG;
} else {
log.info(sm.getString("ajpprotocol.resume", getName()));
}
- public void destroy() throws Exception {
+ public void stop() throws Exception {
+ try {
+ endpoint.stop();
+ } catch (Exception ex) {
+ log.error(sm.getString("ajpprotocol.endpoint.stoperror"), ex);
+ throw ex;
+ }
if (log.isInfoEnabled())
log.info(sm.getString("ajpprotocol.stop", getName()));
+ }
+
+ public void destroy() throws Exception {
+ if (log.isInfoEnabled())
+ log.info(sm.getString("ajpprotocol.destroy", getName()));
endpoint.destroy();
if (tpOname!=null)
Registry.getRegistry(null, null).unregisterComponent(tpOname);
# AjpAprProtocol
#
+ajpprotocol.destroy=Destroying Coyote AJP/1.3 on {0}
ajpprotocol.endpoint.initerror=Error initializing endpoint
ajpprotocol.endpoint.starterror=Error starting endpoint
+ajpprotocol.endpoint.stoperror=Error stopping endpoint
ajpprotocol.init=Initializing Coyote AJP/1.3 on {0}
ajpprotocol.proto.error=Error reading request, ignored
ajpprotocol.getattribute=Attribute {0}
}
@Override
- public void destroy() throws Exception {
+ public void stop() throws Exception {
+ try {
+ endpoint.stop();
+ } catch (Exception ex) {
+ getLog().error(sm.getString("http11protocol.endpoint.stoperror"), ex);
+ throw ex;
+ }
if(getLog().isInfoEnabled())
getLog().info(sm.getString("http11protocol.stop", getName()));
+ }
+
+ @Override
+ public void destroy() throws Exception {
+ if(getLog().isInfoEnabled())
+ getLog().info(sm.getString("http11protocol.destroy", getName()));
endpoint.destroy();
if( tpOname!=null )
Registry.getRegistry(null, null).unregisterComponent(tpOname);
boolean keptAlive = false;
boolean openSocket = false;
- while (!error && keepAlive && !comet && !async) {
+ while (!error && keepAlive && !comet && !async && !endpoint.isPaused()) {
// Parsing the request header
try {
rp.setStage(org.apache.coyote.Constants.STAGE_ENDED);
- if (comet || async) {
- if (error) {
- inputBuffer.nextRequest();
- outputBuffer.nextRequest();
- recycle();
- return SocketState.CLOSED;
- } else {
- return SocketState.LONG;
- }
+ if (error || endpoint.isPaused()) {
+ inputBuffer.nextRequest();
+ outputBuffer.nextRequest();
+ recycle();
+ return SocketState.CLOSED;
+ } else if (comet || async) {
+ return SocketState.LONG;
} else {
recycle();
return (openSocket) ? SocketState.OPEN : SocketState.CLOSED;
boolean recycle = true;
final KeyAttachment ka = (KeyAttachment)socket.getAttachment(false);
- while (!error && keepAlive && !comet && !async) {
+ while (!error && keepAlive && !comet && !async && !endpoint.isPaused()) {
//always default to our soTimeout
ka.setTimeout(soTimeout);
// Parsing the request header
}//while
rp.setStage(org.apache.coyote.Constants.STAGE_ENDED);
- if (comet || async) {
- if (error) {
- recycle();
- return SocketState.CLOSED;
- } else {
- return SocketState.LONG;
- }
+ if (error || endpoint.isPaused()) {
+ recycle();
+ return SocketState.CLOSED;
+ } else if (comet || async) {
+ return SocketState.LONG;
} else {
- if ( recycle ) {
+ if (recycle) {
recycle();
}
//return (openSocket) ? (SocketState.OPEN) : SocketState.CLOSED;
boolean keptAlive = socketWrapper.isKeptAlive();
- while (started && !error && keepAlive) {
+ while (started && !error && keepAlive && !endpoint.isPaused()) {
// Parsing the request header
try {
}
rp.setStage(org.apache.coyote.Constants.STAGE_ENDED);
- if (error) {
+ if (error || endpoint.isPaused()) {
recycle();
return SocketState.CLOSED;
} else if (async) {
# Http11Protocol
#
+http11protocol.destroy=Destroying Coyote HTTP/1.1 on {0}
http11protocol.endpoint.initerror=Error initializing endpoint
http11protocol.endpoint.starterror=Error starting endpoint
+http11protocol.endpoint.stoperror=Error stopping endpoint
http11protocol.init=Initializing Coyote HTTP/1.1 on {0}
http11protocol.proto.error=Error reading request, ignored
http11protocol.proto.ioexception.debug=IOException reading request
}
}
- public abstract void pause();
- public abstract void resume();
+
+ public abstract void init() throws Exception;
public abstract void start() throws Exception;
+
+ /**
+ * Pause the endpoint, which will stop it accepting new connections.
+ */
+ public void pause() {
+ if (running && !paused) {
+ paused = true;
+ unlockAccept();
+ // Heuristic: Sleep for a while to ensure pause of the endpoint
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ // Ignore
+ }
+ }
+ }
+
+ /**
+ * Resume the endpoint, which will make it start accepting new connections
+ * again.
+ */
+ public void resume() {
+ if (running) {
+ paused = false;
+ }
+ }
+
+ public abstract void stop() throws Exception;
public abstract void destroy() throws Exception;
- public abstract void init() throws Exception;
public String adjustRelativePath(String path, String relativeTo) {
File f = new File(path);
}
/**
- * Pause the endpoint, which will make it stop accepting new sockets.
- */
- @Override
- public void pause() {
- if (running && !paused) {
- paused = true;
- unlockAccept();
- }
- }
-
-
- /**
- * Resume the endpoint, which will make it start accepting new sockets
- * again.
- */
- @Override
- public void resume() {
- if (running) {
- paused = false;
- }
- }
-
-
- /**
* Stop the endpoint. This will cause all processing threads to stop.
*/
public void stop() {
+ if (!paused) {
+ pause();
+ }
if (running) {
running = false;
unlockAccept();
*/
protected boolean processSocketWithOptions(long socket) {
try {
- getExecutor().execute(new SocketWithOptionsProcessor(socket));
+ // During shutdown, executor may be null - avoid NPE
+ if (running) {
+ getExecutor().execute(new SocketWithOptionsProcessor(socket));
+ }
} catch (RejectedExecutionException x) {
log.warn("Socket processing request was rejected for:"+socket,x);
return false;
}
@Override
- public void pause() {
- if (running && !paused) {
- paused = true;
- unlockAccept();
- }
- }
-
- @Override
- public void resume() {
- if (running) {
- paused = false;
- }
- }
-
public void stop() {
+ if (!paused) {
+ pause();
+ }
if (running) {
running = false;
unlockAccept();
try {
SocketWrapper<Socket> wrapper = new SocketWrapper<Socket>(socket);
wrapper.setKeepAliveLeft(getMaxKeepAliveRequests());
- getExecutor().execute(new SocketProcessor(wrapper));
+ // During shutdown, executor may be null - avoid NPE
+ if (running) {
+ getExecutor().execute(new SocketProcessor(wrapper));
+ }
} catch (RejectedExecutionException x) {
log.warn("Socket processing request was rejected for:"+socket,x);
return false;
}
- /**
- * Return the state of the endpoint.
- *
- * @return true if the endpoint is running, false otherwise
- */
- @Override
- public boolean isRunning() {
- return running;
- }
-
-
- /**
- * Return the state of the endpoint.
- *
- * @return true if the endpoint is paused, false otherwise
- */
- @Override
- public boolean isPaused() {
- return paused;
- }
-
-
// ----------------------------------------------- Public Lifecycle Methods
/**
- * Pause the endpoint, which will make it stop accepting new sockets.
- */
- @Override
- public void pause() {
- if (running && !paused) {
- paused = true;
- unlockAccept();
- }
- }
-
-
- /**
- * Resume the endpoint, which will make it start accepting new sockets
- * again.
- */
- @Override
- public void resume() {
- if (running) {
- paused = false;
- }
- }
-
-
- /**
* Stop the endpoint. This will cause all processing threads to stop.
*/
public void stop() {
+ if (!paused) {
+ pause();
+ }
if (running) {
running = false;
unlockAccept();
Make sure async timeout thread is stopped when the connector is stopped.
(markt)
</fix>
+ <fix>
+ <bug>49802</bug>: Re-factor connector pause, stop and destroy methods so
+ that calling any of those methods has the expected results. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Jasper">