ArchiveOrangemail archive

dev.httpd.apache.org


(List home) (Recent threads) (11 other Apache HTTPD lists)

Subscription Options

  • RSS or Atom: Read-only subscription using a browser or aggregator. This is the recommended way if you don't need to send messages to the list. You can learn more about feed syndication and clients here.
  • Conventional: All messages are delivered to your mail address, and you can reply. To subscribe, send an email to the list's subscribe address with "subscribe" in the subject line, or visit the list's homepage here.
  • Moderate traffic list: up to 30 messages per day
  • This list contains about 134,277 messages, beginning Feb 1995
  • 4 messages added yesterday
Report the Spam
This button sends a spam report to the moderator. Please use it sparingly. For other removal requests, read this.
Are you sure? yes no

checking for EWOULDBLOCK/EAGAIN *inside* APR

Ad
Jeff Trawick 955133815Fri, 07 Apr 2000 18:56:55 +0000 (UTC)
For the moment, let's ignore the issue about what the *caller* of APR
does to handle EWOULDBLOCK/EAGAIN (I think Ryan wants me to call his
canonicalizer then compare the canonicalized ap_status_t with
APR_EAGAIN).  When I asked Ryan how the app-layer code I posted would
be made to work, I neglected to remind him that there were issues both
inside and outside of APR.

Surely we don't need to call a canonicalizer *inside* APR?

There is a bunch of code like this in APR that I need to change so
that it works on OS/390 and other platforms where EWOULDBLOCK !=
EAGAIN:

ap_status_t ap_send(ap_socket_t *sock, const char *buf, ap_ssize_t *len)
{
    ssize_t rv;    do {
        rv = write(sock->socketdes, buf, (*len));
    } while (rv == -1 && errno == EINTR);>>> if (rv == -1 && errno == EAGAIN && sock->timeout != 0) {<<<
        ap_status_t arv = wait_for_io_or_timeout(sock, 0);
        if (arv != APR_SUCCESS) {
            *len = 0;
            return arv;
        }

(Actually I've already changed it privately; Apache is busted on
OS/390 otherwise.)

Does anyone have a better solution than this that Ryan would agree
with? 

my current solution inside APR:

>>> if (rv == -1 && 
        (errno == EAGAIN || errno == EWOULDBLOCK) && 
        sock->timeout != 0) {<<<

In truth, if I simply change EAGAIN to EWOULDBLOCK it will work on
Linux, FreeBSD, OS/390, AIX, Solaris, and I suspect quite a few other
flavors.  The solution I'm using currently is certainly safer.

Ben mentioned a concern that something like "(errno == EAGAIN || errno
== EWOULDBLOCK)" might lead to a compiler warning.  gcc -Wall doesn't
emit one, however.  If we find a better solution later, we can always
handle it then.

Looking forward to a crisp consensus when I get back Sunday/Monday
(ha!), 

Jeff
Ben Hyde 955135131Fri, 07 Apr 2000 19:18:51 +0000 (UTC)
Jeff Trawick writes: > Ben mentioned a concern that something like "(errno == EAGAIN || errno > == EWOULDBLOCK)" might lead to a compiler warning. gcc -Wall doesn't > emit one, however. If we find a better solution later, we can always > handle it then.
I believe -Wall notices: switch(errno){ case EAGAIN: case EWOULDBLOCK: ... ... } Not that it's imporant. Oh, fyi ben != Ben, and I'm ben. Ben has a bunker, sadly all I have is a big basement.
rbb955136220Fri, 07 Apr 2000 19:37:00 +0000 (UTC)
I must really be missing something.  But, I'll try one more time.

In Apache 1.3, in src/main/buff.c on line 718 among others, we check for
errno != EAGAIN.  This works on every platform that 1.3 works on.  We are
not checking for EWOULDBLOCK here.  Why can't we do the same thing for 2.0
in APR?

I am under the impression, and this may be what I am missing, that Apache
1.3 can be downloaded and run on OS/390 platforms. 

Why is it that this works for 1.3 but not for 2.0?

If this is a real bug, then just check for EAGAIN and EWOULDBLOCK in APR,
and then return errno.  You are going to need to call
ap_canonicalize_error in your app regardless of what Unix platforms do,
because Windows doesn't return either one of these two errors.

Ryan
dean gaudet 955137050Fri, 07 Apr 2000 19:50:50 +0000 (UTC)
any compiler worth its salt will remove a redundant comparison.

-dean

% cat tr.c
int foo(int a)
{
        return a == 11 || a == 11;
}
% gcc -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/specs
gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)
% gcc -O -S -c tr.c
% cat tr.s
        .file   "tr.c"
        .version        "01.01"
gcc2_compiled.:
.text
        .align 4
.globl foo
        .type    foo,@function
foo:
        pushl %ebp
        movl %esp,%ebp
        cmpl $11,8(%ebp)
        sete %al
        andl $255,%eax
        leave
        ret
.Lfe1:
        .size    foo,.Lfe1-foo
        .ident  "GCC: (GNU) egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)"
Jeff Trawick 955139932Fri, 07 Apr 2000 20:38:52 +0000 (UTC)
> I must really be missing something. But, I'll try one more time. > > In Apache 1.3, in src/main/buff.c on line 718 among others, we check for > errno != EAGAIN. This works on every platform that 1.3 works on. We are > not checking for EWOULDBLOCK here. Why can't we do the same thing for 2.0 > in APR?
I cannot answer your question with 100% certainty. A very quick grep/ browse of 1.3 (ignoring Win32 paths) shows that ap_bnonblock() is called only from ap_send_fb_length(), and that only ap_bnonblock() has code for Unix to mark a socket non-blocking. Thus, I think the code you point out is basically (or at least mostly) a no-op on 1.3 Unix. The point at which I hit the error on 2.0 is when we are waiting for the request, so I am not close to that point. Fairly frequently the GET is not there at the point that we wake up and try the first read()-type call to probe for data. As far as getting EAGAIN/EWOULDBLOCK on a send()-type call after ap_send_fb_length(): no useful comments really... There are some implementation details in OS/390 TCP/IP which I think make it less likely to hit the BSD-style send-buffer-full situation. I can say without a shadow of a doubt that an app on OS/390 that uses the UNIX APIs definitely does not get something that is equal to EAGAIN when a read is attempted on a non-blocking socket and no data is available. Furthermore, I saw (in dbx) the lack of checking for EWOULDBLOCK lead to a real problem.
> If this is a real bug, then just check for EAGAIN and EWOULDBLOCK in APR, > and then return errno. You are going to need to call > ap_canonicalize_error in your app regardless of what Unix platforms do, > because Windows doesn't return either one of these two errors.
o.k. I think we're in agreement on what I should change. Thanks, Jeff
Home | About | Privacy