Re: [PATCH] apr_file_writev() on UNIX

2004-10-06 Thread Jean-Jacques Clar


Lets agree there is a bug in the way the function is used in
mod_disk_cache. That will be looked at.

As far as not having a bug in the !HAS_WRITEV implementation,
I disagree.
The current implementation does not havea singlechance of
being successful if there is more than 1 vector. This does
not make sense to me. Let assume the write part is successful,
the function will return apr_success but has completely failed
to his task.
In the header file there is a remark saying that apr_file_writev
is available even if the underlying os doesn't provide writev().
Why providing something that it is going to fail every single
time?

Is the current implementation meets the expectation of others and
I am the only one that see something wrong here?
Thanks,
Jean-Jacques
 Joe Orton [EMAIL PROTECTED] 10/05/04 2:40 PM 
On Tue, Oct 05, 2004 at 11:23:35AM -0600, Jean-Jacques Clar wrote:  [EMAIL PROTECTED] 10/05/04 12:16 AM  On Mon, Oct 04, 2004 at 06:11:57PM -0600, Jean-Jacques Clar wrote:  If HAS_WRITEV is not defined the current code  will just push the first vector to the target.  The function should write all the vectors or none.  There is no guarantee that writev(2) writes all the vectors, it's allowed to return short just like write(2) is, so why should apr_file_writev() give such a guarantee only for the non-writev-based implementation? If HAS_WRITEV is not defined, there is a bug inside apr_file_writev(). Only the first vector will be written to the file. How do you think that bug should be fixed?I don't think that's a bug. apr_file_writev() should be allowed toreturn short, as the writev()-based implementation may already do thistoo. So the !HAS_WRITEV implementation is valid. apr_file_writev() is used multiple times without alternatives in mod_disk_cache.c and the current implementation is failing without informing the caller or any failure if writev() is not available.Right, the bug is in how the function is used. It's the same as callingapr_file_write() and presuming it won't return short. The fix is tocall apr_file_write_full(), in that case. In this case, there is noapr_file_writev_full(), so that should be fixed.joe


Re: [PATCH] apr_file_writev() on UNIX

2004-10-06 Thread Cliff Woolley
On Wed, 6 Oct 2004, Jean-Jacques Clar wrote:

 Why providing something that it is going to fail every single
 time?

That was my original thought.  I wouldn't mind seeing both the caller as
well as the !HAS_WRITEV cases fixed (or fixed if you prefer) for this
reason.

--Cliff


Re: [PATCH] apr_file_writev() on UNIX

2004-10-06 Thread William A. Rowe, Jr.
At 11:12 AM 10/6/2004, you wrote:
 
As far as not having a bug in the !HAS_WRITEV implementation,
I disagree.
The current implementation does not have a single chance of
being successful if there is more than 1 vector. This does
not make sense to me. Let assume the write part is successful,
the function will return apr_success but has completely failed
to his task.

That's only partially true - we should never return for a blocking
socket writev, only for a nonblocking one when the socket would
block on the remaining vector(s).

In the header file there is a remark saying that apr_file_writev
is available even if the underlying os doesn't provide writev().
Why providing something that it is going to fail every single
time?

Does writev() return *success* on a partial-write?  I very much
doubt it (EINTR, EWOULDBLOCK or EAGAIN is what I would expect.)

The performance of the existing code is obviously sub-par, and we
should loop through all the vectors until we get a hiccup.  At that
point the user can retry the remaining vectors.

I should make a point that it seems 'wrong' we implemented this
lie - there is another property of writev() that we've ignored...

writev() will gather up the vectors into a single datagram, even
when nagle is off.  So this implementation leaves us potentially
sending dozens of datagrams for a few dozen very small buffers.

It seems a true implementation would use it's own buffer to concat
all of the smaller fragments into a single packet - the pain in
cpu is nominal compared to the pain of multiple datagram processing.

Bill



Re: [PATCH] apr_file_writev() on UNIX

2004-10-06 Thread Joe Orton
On Wed, Oct 06, 2004 at 10:12:33AM -0600, Jean-Jacques Clar wrote:
 Lets agree there is a bug in the way the function is used in
 mod_disk_cache. That will be looked at.
  
 As far as not having a bug in the !HAS_WRITEV implementation,
 I disagree.
 The current implementation does not have a single chance of
 being successful if there is more than 1 vector. This does
 not make sense to me. Let assume the write part is successful,
 the function will return apr_success but has completely failed
 to his task.

You're missing the point.  It is valid for apr_file_writev() to return
APR_SUCCESS and update *nbytes to less than the total number of bytes in
the vector.  The writev()-based implementation *may* do that.  The
non-writev-based implementation *will* do it, if passed a vector of more
than one buffer.  But the caller must cope with it either way.

joe


Re: [PATCH] apr_file_writev() on UNIX

2004-10-06 Thread Jean-Jacques Clar

 Joe Orton [EMAIL PROTECTED] 10/06/04 12:46 PM 
On Wed, Oct 06, 2004 at 10:12:33AM -0600, Jean-Jacques Clar wrote: As far as not having a bug in the !HAS_WRITEV implementation, I disagree. The current implementation does not have a single chance of being successful if there is more than 1 vector. This does not make sense to me. Let assume the write part is successful, the function will return apr_success but has completely failed to his task.You're missing the point. It is valid for apr_file_writev() to returnAPR_SUCCESS and update *nbytes to less than the total number of bytes inthe vector. The writev()-based implementation *may* do that. Thenon-writev-based implementation *will* do it, if passed a vector of morethan one buffer. But the caller must cope with it either way.Joe,

I clearly understand "your" point, but could I disagree with it?
I have a problem with the *will* fail. Both option should
have a *may* be successful. 
I don't think our views on that point are reconcilable, 
but maybe others could share whatever they think
the current way is right or wrong.
Regards,
Jean-Jacques


[PATCH] apr_file_writev() on UNIX

2004-10-05 Thread Jean-Jacques Clar


IfHAS_WRITEV is not defined the current code
will just push the first vector to the target.
The function should write all the vectors or none.
I propose the following patch, comments will be
appreciated:
Thanks for looking.
JJ

Index: srclib/apr/file_io/unix/readwrite.c===RCS file: /home/cvs/apr/file_io/unix/readwrite.c,vretrieving revision 1.90diff -u -r1.90 readwrite.c--- srclib/apr/file_io/unix/readwrite.c2 Aug 2004 09:47:48 -1.90+++ srclib/apr/file_io/unix/readwrite.c4 Oct 2004 22:41:45 -@@ -241,8 +241,22 @@ return APR_SUCCESS; }#else- *nbytes = vec[0].iov_len;- return apr_file_write(thefile, vec[0].iov_base, nbytes);+ apr_status_t rv;+ int i, bytes = 0;++ for (i = 0; i  nvec; i++) {+ *nbytes = vec[i].iov_len;+ if ((rv = apr_file_write(thefile, vec[i].iov_base, nbytes)) != APR_SUCCESS) {+ *nbytes = bytes;+ return rv;+ }+ else {+ bytes += *nbytes;+ }+ }+ *nbytes = bytes;+ + return APR_SUCCESS;#endif}



Re: [PATCH] apr_file_writev() on UNIX

2004-10-05 Thread Cliff Woolley
On Mon, 4 Oct 2004, Jean-Jacques Clar wrote:

 If HAS_WRITEV is not defined the current code
 will just push the first vector to the target.

Oooh, that sucks.  Good catch.


 The function should write all the vectors or none.
 I propose the following patch, comments will be

+1, with the following nit:


 +apr_status_t rv;
 +int i, bytes = 0;
 +
 +for (i = 0; i  nvec; i++) {
 +*nbytes = vec[i].iov_len;

Is there really a point to the above line?  *nbytes will always be
overwritten before returning anyway, so why not just skip this line and
then:

 +if ((rv = apr_file_write(thefile, vec[i].iov_base, nbytes)) !=
 APR_SUCCESS) {
 +*nbytes = bytes;
 +return rv;
 +}
 +else {
 +bytes += *nbytes;

bytes += vec[i].iov_len;

 +}
 +}
 +*nbytes = bytes;
 +
 +return APR_SUCCESS;

Thoughts?

--Cliff


Re: [PATCH] apr_file_writev() on UNIX

2004-10-05 Thread Jean-Jacques Clar

 Cliff Woolley [EMAIL PROTECTED] 10/04/04 7:08 PM 
 + *nbytes = vec[i].iov_len;Is there really a point to the above line? *nbytes will always beoverwritten before returning anyway, so why not just skip this line andthen: + if ((rv = apr_file_write(thefile, vec[i].iov_base, nbytes)) != APR_SUCCESS) { + *nbytes = bytes; + return rv; + } + else { + bytes += *nbytes;bytes += vec[i].iov_len;Thoughts?
I thought that the nbytes on the call for apr_file_write() is the number of bytes to write.
Does that info needs to be passed in?
Should then be set to iov_len before the call. What do I miss there?


Thanks,
JJ


Re: [PATCH] apr_file_writev() on UNIX

2004-10-05 Thread Cliff Woolley
On Mon, 4 Oct 2004, Jean-Jacques Clar wrote:

  +if ((rv = apr_file_write(thefile, vec[i].iov_base, nbytes))

 I thought that the nbytes on the call for apr_file_write() is the
 number of bytes to write.

Oh crap, I'm sorry, I totally missed that.  *blush*

+1 to the patch as-is.

--Cliff


Re: [PATCH] apr_file_writev() on UNIX

2004-10-05 Thread jorton
On Mon, Oct 04, 2004 at 06:11:57PM -0600, Jean-Jacques Clar wrote:
 If HAS_WRITEV is not defined the current code
 will just push the first vector to the target.
 The function should write all the vectors or none.

There is no guarantee that writev(2) writes all the vectors, it's
allowed to return short just like write(2) is, so why should
apr_file_writev() give such a guarantee only for the non-writev-based
implementation?

What you're looking for, perhaps, is an apr_file_writev_full(), which
guarantees all bytes are written, or failure?

joe


Re: [PATCH] apr_file_writev() on UNIX

2004-10-05 Thread Jean-Jacques Clar

 [EMAIL PROTECTED] 10/05/04 12:16 AM 
On Mon, Oct 04, 2004 at 06:11:57PM -0600, Jean-Jacques Clar wrote: If HAS_WRITEV is not defined the current code will just push the first vector to the target. The function should write all the vectors or none.There is no guarantee that writev(2) writes all the vectors, it'sallowed to return short just like write(2) is, so why shouldapr_file_writev() give such a guarantee only for the non-writev-basedimplementation?If HAS_WRITEV is not defined, there is a bug inside apr_file_writev().
Only the first vector will be written to the file.
How do you think that bug should be fixed?

apr_file_writev() is used multiple times without alternatives in mod_disk_cache.c 
and the current implementation is failing without informing the caller or any
failure if writev() is not available. Do you see a better solution than fixing
apr_file_writev() for that case?
Maybe the question is why do we need to have the HAS_WRITEV define?
Are there any Unix based system that do not have writev() implemented?
What you're looking for, perhaps, is an apr_file_writev_full(), whichguarantees "all bytes are written, or failure"?
I am not looking for replacement, there arevectors that needs to be written
to a filein the current case.
Thanks, 
JJ


Re: [PATCH] apr_file_writev() on UNIX

2004-10-05 Thread Joe Orton
On Tue, Oct 05, 2004 at 11:23:35AM -0600, Jean-Jacques Clar wrote:
  [EMAIL PROTECTED] 10/05/04 12:16 AM 
 On Mon, Oct 04, 2004 at 06:11:57PM -0600, Jean-Jacques Clar wrote:
  If HAS_WRITEV is not defined the current code
  will just push the first vector to the target.
  The function should write all the vectors or none.
 
 There is no guarantee that writev(2) writes all the vectors, it's
 allowed to return short just like write(2) is, so why should
 apr_file_writev() give such a guarantee only for the non-writev-based
 implementation?

 If HAS_WRITEV is not defined, there is a bug inside apr_file_writev().
 Only the first vector will be written to the file.
 How do you think that bug should be fixed?

I don't think that's a bug.  apr_file_writev() should be allowed to
return short, as the writev()-based implementation may already do this
too.  So the !HAS_WRITEV implementation is valid.

 apr_file_writev() is used multiple times without alternatives in
 mod_disk_cache.c and the current implementation is failing without
 informing the caller or any failure if writev() is not available.

Right, the bug is in how the function is used.  It's the same as calling
apr_file_write() and presuming it won't return short.  The fix is to
call apr_file_write_full(), in that case.  In this case, there is no
apr_file_writev_full(), so that should be fixed.

joe


Re: [PATCH] apr_file_writev() on UNIX

2004-10-05 Thread Cliff Woolley
On Tue, 5 Oct 2004, Joe Orton wrote:

 Right, the bug is in how the function is used.  It's the same as calling
 apr_file_write() and presuming it won't return short.  The fix is to
 call apr_file_write_full(), in that case.  In this case, there is no
 apr_file_writev_full(), so that should be fixed.

Sounds like a reasonable explanation.

Thanks, Joe.

--Cliff