HTTPCLIENT-1127: fixed dead-lock between SingleClientConnManager and AbstractPooledConnAdapter

git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1179609 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Oleg Kalnichevski 2011-10-06 13:07:33 +00:00
parent 62c57991f5
commit 0c00bef71e
2 changed files with 23 additions and 24 deletions

View File

@ -78,7 +78,7 @@ public abstract class AbstractClientConnAdapter implements ManagedClientConnecti
* This attribute MUST NOT be final, so the adapter can be detached * This attribute MUST NOT be final, so the adapter can be detached
* from the connection manager without keeping a hard reference there. * from the connection manager without keeping a hard reference there.
*/ */
private volatile ClientConnectionManager connManager; private final ClientConnectionManager connManager;
/** The wrapped connection. */ /** The wrapped connection. */
private volatile OperatedClientConnection wrappedConnection; private volatile OperatedClientConnection wrappedConnection;
@ -114,9 +114,8 @@ public abstract class AbstractClientConnAdapter implements ManagedClientConnecti
* Detaches this adapter from the wrapped connection. * Detaches this adapter from the wrapped connection.
* This adapter becomes useless. * This adapter becomes useless.
*/ */
protected synchronized void detach() { protected void detach() {
wrappedConnection = null; wrappedConnection = null;
connManager = null; // base class attribute
duration = Long.MAX_VALUE; duration = Long.MAX_VALUE;
} }
@ -303,17 +302,18 @@ public abstract class AbstractClientConnAdapter implements ManagedClientConnecti
} }
} }
public synchronized void releaseConnection() { public void releaseConnection() {
synchronized (connManager) {
if (released) { if (released) {
return; return;
} }
released = true; released = true;
if (connManager != null) {
connManager.releaseConnection(this, duration, TimeUnit.MILLISECONDS); connManager.releaseConnection(this, duration, TimeUnit.MILLISECONDS);
} }
} }
public synchronized void abortConnection() { public void abortConnection() {
synchronized (connManager) {
if (released) { if (released) {
return; return;
} }
@ -323,12 +323,11 @@ public abstract class AbstractClientConnAdapter implements ManagedClientConnecti
shutdown(); shutdown();
} catch (IOException ignore) { } catch (IOException ignore) {
} }
if (connManager != null) {
connManager.releaseConnection(this, duration, TimeUnit.MILLISECONDS); connManager.releaseConnection(this, duration, TimeUnit.MILLISECONDS);
} }
} }
public synchronized Object getAttribute(final String id) { public Object getAttribute(final String id) {
OperatedClientConnection conn = getWrappedConnection(); OperatedClientConnection conn = getWrappedConnection();
assertValid(conn); assertValid(conn);
if (conn instanceof HttpContext) { if (conn instanceof HttpContext) {
@ -338,7 +337,7 @@ public abstract class AbstractClientConnAdapter implements ManagedClientConnecti
} }
} }
public synchronized Object removeAttribute(final String id) { public Object removeAttribute(final String id) {
OperatedClientConnection conn = getWrappedConnection(); OperatedClientConnection conn = getWrappedConnection();
assertValid(conn); assertValid(conn);
if (conn instanceof HttpContext) { if (conn instanceof HttpContext) {
@ -348,7 +347,7 @@ public abstract class AbstractClientConnAdapter implements ManagedClientConnecti
} }
} }
public synchronized void setAttribute(final String id, final Object obj) { public void setAttribute(final String id, final Object obj) {
OperatedClientConnection conn = getWrappedConnection(); OperatedClientConnection conn = getWrappedConnection();
assertValid(conn); assertValid(conn);
if (conn instanceof HttpContext) { if (conn instanceof HttpContext) {

View File

@ -105,7 +105,7 @@ public abstract class AbstractPooledConnAdapter extends AbstractClientConnAdapte
* This adapter becomes useless. * This adapter becomes useless.
*/ */
@Override @Override
protected synchronized void detach() { protected void detach() {
poolEntry = null; poolEntry = null;
super.detach(); super.detach();
} }