httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
Subject Re: Errno code in APR again.
Date Thu, 06 Apr 2000 19:59:40 GMT

> 1.3 on UNIX:
> socket is blocking, we time out via an alarm() call; don't care about
> 1.3 on Win32:
> socket is nonblocking, we time out via select()-type call, we do care
> 2.0 on UNIX:
> socket is nonblocking, we time out via select()-type call, we do care

First of all, this still doesn't answer my original question.  We are at
times checking for EAGAIN in 1.3, and we aren't checking for EWOULDBLOCK
at the same time.  I am still wondering why this is an issue now.

Second of all, I posted the correct code:

    rv = iol_read(fb->iol, buf, nbyute, bytes_read);
    if (rv == APR_SUCCESS && *byutes_read ==0) {
        fb->flags |= B_EOF;
    else if (rv != APR_SUCCESS) {
        fb->berrno = rv;
        fb->saved_errno = rv;
        rv = ap_canonicalize_error(rv);
        if (rv != APR_EAGAIN) {
            doerror(fb, B_RD);
    return rv;

Granted, at the time I added a sarcastic ifdef in there as well.

This will work.  There are only two ways to deal with error values in a
portable manner.  1)  Return common error codes always or 2) return
non-common error codes and make the programmer convert them.

Either way, the conversion needs to be done.  The problem as I see it, is
that with option 1 the conversion is always done, even if the error is
just going to be used to generate a string.  If the value is used to
generate a string, it needs to be converted back to a platform error code
before the string can be generated.  This is two conversions when none
were needed.  If the value is going to be used to determine what the
program does, the code has already been converted.  This is one
conversion, and it is necessary.

Option 2 leaves it up to the programmer to determine when they need a
common code.  If we are generating an error string, there are no
conversions performed.  If we are determining what the program does, we
have to convert.  This is one conversion and is it necessary.  Oh, and on
MOST unix platforms, there is no conversion and a smart compiler will
ignore the ap_canonicalize_error function.  This is because on most unixes
this function will look like:

int ap_canonicalize_error(ap_status_t rv){
    return rv;

If you want to handle the case under discussion this function changes to

int ap_canonicalize_error(ap_status_t rv) {
    if (rv == EWOULDBLOCK)
        return EAGAIN;
    return rv;

Again, any good optimizing compiler will recgonize this and the conversion
will be a no-op on most Unixes.  Is this great for other platforms?  No,
but it does work, and it's the best thing we have found so far.

I see no other options here.  What am I missing?

Ryan Bloom               
406 29th St.
San Francisco, CA 94131

View raw message