You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Mike Anderson <MM...@novell.com> on 2001/03/22 00:40:10 UTC

Re: [PATCH] [Bug 1001] - available() method on ServletInputStreamalways returns 0

Costin,

Thanks for the response.  I agree that available is supposed to return how many
bytes can be returned without a read() on the "primary".  The second diff file 
has patches that implement available this way for everything except the 
JNI connector.  My only concern with this (2nd) set of patches was that the
AJP13 connector would return how much was available in it's own buffer but 
that buffer was never reloaded unless a read was requested the exhausts the
buffer and still wanted more data.  The only way I could see to get around this
was to either have available return the total number of bytes that could be read
(bad because a read will most likely block) or implement refillBuffer as an
asynchronous method that would actually fill the buffer in the background based
on some signal from the main thread.  That type of implementation could also be 
used to clean up the JNI connector as well.  I just didn't want to introduce that
level of complexity this close to release ;-)  I'll wait to here from Marc and start
looking at the 3.3 code to what it will take there.

Mike

>>> cmanolache@yahoo.com 03/21/01 03:23PM >>>
>Mike, 
>
>I'm not sure I understand ( not your mail - the "available" definition ).
>
>Isn't availabe supposed to return how many bytes can be returned without a
>read() on the "primary" source ( that would block ) ? 
>
>What you describe is slightly different - and I'm not sure it's a good
>idea. In any case, I would prefer the second choice - have the protocol
>return what it has in it's buffers ( if any ). 
>
>Of course, a big question is what is available :-) If the data has been
>read by Apache but not yet sent to tomcat - is it available ? Probably so
>( AFAIK this shouldn't happen - actual read from network is driven by a
>tomcat request and no data is buffered on apache ). But that would be a
>bit too complex even for 3.3 ( but may be implemented in a future ajp14 )
>
>I don't think this would have any significant impact on code stability -
>since you replace a method that returns 0 to something a bit more acurate,
>and I see no problem with adding a patch to 3.3 ( 3.2 is quite close to 
>a release, it's up to Marc to decide ). But I'm a bit concerned about the
>corectness of the result.
>
>
>Costin  
>
>
>
>
>On Wed, 21 Mar 2001, Mike Anderson wrote:
>
>> I noticed that this bug was marked RESOLVED/LATER and was wondering if there was any way to get this into 3.2.2 since that is the version that is closest to being released.  >I've already found 2 ways to fix this issue but am willing to abide by the groups decision and concentrate on getting this into the 3.3 release instead.
>> The 2 ways to fix this are:
>> 
>> 1.  In BufferedServletInputStream, implement an available() method that returns limit - bytesRead or 0 whichever is greater.  The limit class variable is set to the value of the Content-Length header and bytesRead is the number of bytes read since limit was set (see the attached diff1.txt).  This is the easy fix but doesn't address the feature of available that says it will return the number of bytes that can be read "without blocking".  Obviously, if there is a large amount of data, a read will most likely block at some point depending on how much is asked for, however this prevents a condition where one of the adapters returns 0 because a read hasn't actually been requested from the webserver.
> 
> 2.  Update BufferedServletInputStream to call reqA.available and then update the following files to provide this interface:
>   Request.java
>   RequestImpl.java
>   HttpRequestAdapter.java
>   Ajp12ConnectionHandler.java
>   Ajp13ConnectorRequest.java
>   JNIConnectionHandler.java
>   MsgConnector.java
>   TcpConnector.java
> Each of these classes would need to provide an appropriate available() method.  I've also done the work on these files as well (see the attached diff2.txt) but noticed that since some of the protocols (particularly AJP13) actually have to request a read to fill their internal buffer, the adapter (i.e. Ajp13ConnectorRequest.java) will return a 0 if doRead is called and it exactly empties the internal buffer.  Also the JNIRequestAdapter (in JNIConnectionHandler.java) makes a native call back into the webserver to do the reads and so available is implemented similar to #1 above; it just returns the max of contentLength - bytesRead or 0.  This was because I'm not sure of a way to imp
> 
> After testing both of these, implementation 1 is actually faster and more reliable.  Typically if someone is calling available and they get back a 0, they would block the thread anyways and so it makes some sense to let it block on the read plus it gets around the issue of an adapter requiring one of it's read methods to be called to actually have something available.
> 
> Any response positive or negative would be appreciated so that I know where to focus my energy (i.e. 3.2.2 or 3.3).
> 
> 
> 
>