Mike,

I agree with your assessment that it must necessarily be unsafe to call HttpConnection.releaseConnection() in a multithreaded environment. Since only the method and its "stream" "knows" when its response has been fully consumed, you can never guarantee that the connection might be recycled at some point. In some sense, this isn't really a multi-threading issue, so much as it is a sequencing issue. Consider the following scenario.

Execute method A.
Save method A's "connection"
Fully read its response.

Execute method B - (happens to reuse connection from A)
"release" method A's connection as "cleanup" (we don't explicitly disallow this sequencing in the API).
read method B's response - exception thrown, as its connection was closed.

The only way that I can see around this is to change HttpConnection to be a facade around another class that looks a lot like its current implementation. In that way, when a connection is "released", the facade can be put into a state where subsequent "releases" will be ignored, however the underlying "HttpConnection" may already be in use elsewhere - by a different thread or subsequent request in the same thread.

Also, the HttpConnection has a "lastResponseInputStream" - calling "close" on that stream (if there is one), will result in a notification to the method that the response has been consumed. The only trick here is a re-entrance problem. When the method sees that the response body has been consumed, it releases the connection. As a result, you don't want HttpConnection.releaseConnection() to call lastResponseInputStream.close(), or you don't want the HttpMethodBase to call HttpConnection.releaseConnection(). A different function on HttpConnection, specifically for the method releasing the connection, might solve that problem - methodDoneWithConnection(), or some such thing.

As for the NPE that Aurélien Pernoud noted, I'm not sure where that is coming from.

I might have a chance to look at these problems later today, but if someone else out there has time sooner, that would likely be better, as there is a good chance I won't get to look at this until Tuesday of next week. Hopefully the above is helpful enough to get someone else going in the right direction.

-Eric.

[EMAIL PROTECTED] wrote:

DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=13463>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND INSERTED IN THE BUG DATABASE.

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=13463

Request/Response race condition when doing multiple requests on the same connection.





------- Additional Comments From [EMAIL PROTECTED] 2003-02-14 02:04 -------
Ok, I think I've figured it out. It seems that calling
HttpConnection.releaseConnection() is inherently unsafe. Connections are used
on a per method basis but have no reference to the method they are being used
by. Here's a scenario:

1) A method (A) gets a connection from the connectionManager
2) A is executed
3) The response from A is read fully and the connection is implicitly released
4) The released connection is given to another method (B)
5) Following the execution of A the user code calls
HttpConnection.releaseConnection()
6) The connection is released again
7) B executes but is using a released connection

As you can see the connection was released twice for the method A. Currently
there is no way for a connection to know that it has already been released from
a particular method. This is not a problem if the
HttpMethod.releaseConnection() is always used, since it knows to only release
its connection once.

So, for a quick fix, HttpConnection.releaseConnection() should not be used in
client code. I'll try to come up with a solution that fixes it, but we may just
have to remove it from public consumption.

Mike

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to