Return-Path: Delivered-To: new-httpd-archive@hyperreal.org Received: (qmail 24055 invoked by uid 6000); 18 May 1999 17:31:19 -0000 Received: (qmail 23878 invoked from network); 18 May 1999 17:31:11 -0000 Received: from twinlark.arctic.org (204.107.140.52) by taz.hyperreal.org with SMTP; 18 May 1999 17:31:11 -0000 Received: (qmail 24057 invoked by uid 500); 18 May 1999 17:31:10 -0000 Date: Tue, 18 May 1999 10:31:10 -0700 (PDT) From: Dean Gaudet To: new-httpd@apache.org Subject: Re: [PATCH] select-thread-hybrid-01.patch In-Reply-To: Message-ID: X-Comment: Visit http://www.arctic.org/~dgaudet/legal for information regarding copyright and disclaimer. MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: new-httpd-owner@apache.org Precedence: bulk Reply-To: new-httpd@apache.org On Tue, 18 May 1999, Ryan Bloom wrote: > > > I don't think the abstraction is worth keeping -- you had only one > > "message type" essentialy. > > The abstraction is necessary. There are some operating systems that don't > want to use a complex messaging system like what you are implementing. I > am thinking of one platform already that has already expressed an interest > in using another method for accepting connections. Plus, we most > definately don't want the server on a non-threaded system to use the same > accept model as a threaded platform. Everything I have heard from the > group is that the hybrid server must be able to run in both thread-only > and process-only mode. The accept model abstraction makes this possible. The abstraction is still at the wrong level... it certainly shouldn't be in http_main.c. Yes I know about those other systems. It should be easy to handle them by not sending the messages. I was hoping to have an example for you by now. Just think of those other systems as systems where SO_SNDBUF is infinite... remember I said that I wasn't going to punt back to the event loop when the response fits in the kernel buffers? That means that the response handler will run in a "worker thread". The code should be pretty similar. For example, sending a memory mapped region (mmap or otherwise), here's the interface I'm currently playing with: typedef struct { conn_rec *conn; void *mm; size_t length; void *uap; void (*complete)(void *uap, int bytes_sent); } ap_async_send_mmap_data; API_EXPORT(void) ap_async_send_mmap(ap_async_send_mmap_data *); The handler allocates the structure, sets up the parameters, and calls ap_async_send_mmap. Then it returns OK. The complete function is called in the future when the operation has completed. At this point, another ap_async_send_mmap() could be performed (for example, handling range requests). Folks familiar with async programming should recognize this... it's a pretty standard method. It doesn't require anything special other than a few conventions. > I really hope that when you say fds, you mean sds. If you require all fds > to be non-blocking, including those actually referring to files on disk, > we have a problem. There are too many platforms that do not support > non-blocking fds for files on disk. No I don't require all fds to be non-blocking. Not even unix supports non-blocking disk file fds. That's why I gave separate cases for sending a file versus sending a pipe (i.e. handling a cgi or other external process through a pipe/socket). Dean