manoj       99/10/12 13:37:05

  Modified:    src/main http_protocol.c
  Log:
  Attempt to make ap_send_fb work again. This is untested, but it works
  better than the old version because it compiles.
  
  Revision  Changes    Path
  1.20      +28 -71    apache-2.0/src/main/http_protocol.c
  
  Index: http_protocol.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/main/http_protocol.c,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -d -u -r1.19 -r1.20
  --- http_protocol.c   1999/10/11 22:07:25     1.19
  +++ http_protocol.c   1999/10/12 20:36:56     1.20
  @@ -2056,9 +2056,6 @@
       return total_bytes_sent;
   }
   
  -
  -/* TODO: reimplement ap_send_fb */
  -#if 0
   /*
    * Send the body of a response to the client.
    */
  @@ -2071,82 +2068,46 @@
   {
       char buf[IOBUFSIZE];
       long total_bytes_sent = 0;
  -    register int n, w, o, len, fd;
  -    struct pollfd fds;
  +    long zero_timeout = 0;
  +    int n, w, rc, o;
   
  -    if (length == 0)
  +    if (length == 0) {
           return 0;
  -
  -    /* Make fb unbuffered and non-blocking */
  -    ap_bsetflag(fb, B_RD, 0);
  -    fd = ap_bfileno(fb, B_RD);
  -    ap_bnonblock(fd);
  -#ifdef CHECK_FD_SETSIZE
  -    if (fd >= FD_SETSIZE) {
  -     ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, NULL,
  -         "send body: filedescriptor (%u) larger than FD_SETSIZE (%u) "
  -         "found, you probably need to rebuild Apache with a "
  -         "larger FD_SETSIZE", fd, FD_SETSIZE);
  -     return 0;
       }
  -#endif
   
  -    fds.fd = fd;
  -    fds.events = POLLIN;
  +    /* This function tries to as much as possible through non-blocking
  +     * reads so that it can do writes while waiting for the CGI to
  +     * produce more data. This way, the CGI's output gets to the client
  +     * as soon as possible */
   
  +    ap_bsetopt(fb, BO_TIMEOUT, &zero_timeout);
       while (!ap_is_aborted(r->connection)) {
  -#ifdef NDELAY_PIPE_RETURNS_ZERO
  -     /* Contributed by [EMAIL PROTECTED] for UTS 2.1.2, where the fcntl */
  -     /*   O_NDELAY flag causes read to return 0 when there's nothing */
  -     /*   available when reading from a pipe.  That makes it tricky */
  -     /*   to detect end-of-file :-(.  This stupid bug is even documented */
  -     /*   in the read(2) man page where it says that everything but */
  -     /*   pipes return -1 and EAGAIN.  That makes it a feature, right? */
  -     int afterselect = 0;
  -#endif
  -        if ((length > 0) && (total_bytes_sent + IOBUFSIZE) > length)
  -            len = length - total_bytes_sent;
  -        else
  -            len = IOBUFSIZE;
  -
  -        do {
  -            n = ap_bread(fb, buf, len);
  -#ifdef NDELAY_PIPE_RETURNS_ZERO
  -         if ((n > 0) || (n == 0 && afterselect))
  -             break;
  -#else
  -            if (n >= 0)
  -                break;
  -#endif
  -            if (ap_is_aborted(r->connection))
  +        n = ap_bread(fb, buf, sizeof(buf));
  +        if (n <= 0) {
  +            if (n == 0) {
  +                (void) ap_rflush(r);
                   break;
  -            if (n < 0 && errno != EAGAIN /* ZZZ rethink for threaded impl */)
  +            }
  +            if (n == -1 && errno != EAGAIN) {
  +                r->connection->aborted = 1;
                   break;
  +            }
  +            /* next read will block, so flush the client now */
  +            rc = ap_bflush(r->connection->client);
   
  -            /* we need to block, so flush the output first */
  -            if (ap_bflush(r->connection->client) < 0) {
  -                ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
  -                    "client stopped connection before send body completed");
  -                ap_bsetflag(r->connection->client, B_EOUT, 1);
  +            ap_bsetopt(fb, BO_TIMEOUT, &r->server->timeout);
  +            n = ap_bread(fb, buf, sizeof(buf));
  +            if (n <= 0) {
  +                if (n == 0) {
  +                    (void) ap_rflush(r);
  +                }
                   r->connection->aborted = 1;
                   break;
               }
  -            /*
  -             * we don't care what poll says, we might as well loop back
  -             * around and try another read
  -             */
  -         /* use AP funcs */
  -            poll(&fds, 1, -1);
  -#ifdef NDELAY_PIPE_RETURNS_ZERO
  -         afterselect = 1;
  -#endif
  -        } while (!ap_is_aborted(r->connection));
  -
  -        if (n < 1 || ap_is_aborted(r->connection)) {
  -            break;
  +            ap_bsetopt(fb, BO_TIMEOUT, &zero_timeout);
           }
  +        
           o = 0;
  -
           while (n && !ap_is_aborted(r->connection)) {
               w = ap_bwrite(r->connection->client, &buf[o], n);
               if (w > 0) {
  @@ -2157,7 +2118,7 @@
               else if (w < 0) {
                   if (!ap_is_aborted(r->connection)) {
                       ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
  -                       "client stopped connection before send body 
completed");
  +                        "client stopped connection before rflush completed");
                       ap_bsetflag(r->connection->client, B_EOUT, 1);
                       r->connection->aborted = 1;
                   }
  @@ -2165,14 +2126,10 @@
               }
           }
       }
  -
       SET_BYTES_SENT(r);
       return total_bytes_sent;
   }
  -#endif
  -
   
  -
   /* The code writes MMAP_SEGMENT_SIZE bytes at a time.  This is due to 
Apache's
    * timeout model, which is a timeout per-write rather than a time for the
    * entire transaction to complete.  Essentially this should be small enough
  @@ -2378,7 +2335,7 @@
   API_EXPORT(int) ap_rflush(request_rec *r)
   {
       if (ap_bflush(r->connection->client) < 0) {
  -        if (!r->connection->aborted) {
  +        if (!ap_is_aborted(r->connection)) {
               ap_log_rerror(APLOG_MARK, APLOG_INFO, r,
                   "client stopped connection before rflush completed");
               ap_bsetflag(r->connection->client, B_EOUT, 1);
  
  
  

Reply via email to