Return-Path: Delivered-To: apmail-apr-dev-archive@apr.apache.org Received: (qmail 4331 invoked by uid 500); 13 Oct 2002 12:43:02 -0000 Mailing-List: contact dev-help@apr.apache.org; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: Delivered-To: mailing list dev@apr.apache.org Received: (qmail 4320 invoked from network); 13 Oct 2002 12:43:01 -0000 X-Authentication-Warning: rdu74-177-063.nc.rr.com: trawick set sender to trawick@attglobal.net using -f Sender: trawick@rdu74-177-063.nc.rr.com To: dev@apr.apache.org cc: dev@httpd.apache.org, takasima@poem.ocn.ne.jp.=?iso-2022-jp?b?KBskQjliRWc/PxsoQik=?= Subject: Re: Problem with non-blocking write to pipe References: <20021013114021.3A5963CC6@m-kg271p.ocn.ne.jp> From: Jeff Trawick Date: 13 Oct 2002 08:47:08 -0400 In-Reply-To: <20021013114021.3A5963CC6@m-kg271p.ocn.ne.jp> Message-ID: Lines: 83 User-Agent: Gnus/5.0808 (Gnus v5.8.8) Emacs/21.2 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N "Takashima, Makoto" writes: > Hi, > > I found a problem with non-blocking write to pipe. > > Current code (2.0.43) is as following. > > ------------------------------------------------------------ > httpd-2.0.43/srclib/apr/file_io/unix/readwrite.c:apr_file_write() FYI... this discussion belongs on dev@apr.apache.org... the srclib/apr tree in the httpd-2.0 directory are a copy of the APR project code... > It seems assuming write request never fail when > apr_wait_for_io_or_timeout() succeeded, but it is not true > for pipe. ... > - A write request for {PIPE_BUF} or fewer bytes will have > the following effect: If there is sufficient space > available in the pipe, write() will transfer all the > data and return the number of bytes requested. Otherwise, > write() will transfer no data and return -1 with errno > set to [EAGAIN]. ... boy, this sucks :) no syscall to block until timeout occurs or we can write the whole message... note that most existing users of APR pipes don't care about atomic writes... I wonder if it is appropriate to have a pipe setting that says that atomic is important... if really important, I guess we'd have to sleep before retry... otherwise maybe we should try to write a smaller amount to the pipe... it would be a shame to waste our timeslice, which could cause the reader to have to block too once the other side is empty... > I found this problem on HP-UX11.0 whose PIPE_BUF is 8192 with > CGI that receive more than 8kbytes POST request. > > This problem can be fixed with the following code, however I > do not know if there is better solution other than looping. > > ------------------------------------------------------------ > do { > rv = write(thefile->filedes, buf, *nbytes); > } while (rv == (apr_size_t)-1 && errno == EINTR); > #ifdef USE_WAIT_FOR_IO > if (rv == (apr_size_t)-1 && > (errno == EAGAIN || errno == EWOULDBLOCK) && > thefile->timeout != 0) { > apr_status_t arv = apr_wait_for_io_or_timeout(thefile, NULL, 0); > if (arv != APR_SUCCESS) { > *nbytes = 0; > return arv; > } > else { > do { > rv = write(thefile->filedes, buf, *nbytes); > > /* write request of {PIPE_BUF} bytes or less may fail */ > /* because it is atomic when writing to pipe or FIFO */ > while (rv == (apr_size_t)-1 && > *nbytes < PIPE_BUF && errno == EAGAIN) > { > apr_sleep(10000); /* sleep ~10ms */ > rv = write(thefile->filedes, buf, *nbytes); > } > } while (rv == (apr_size_t)-1 && errno == EINTR); > } > } > #endif > ------------------------------------------------------------ > > > -- > takasima@poem.ocn.ne.jp > -- Jeff Trawick | trawick@attglobal.net Born in Roswell... married an alien...