From owner-freebsd-chat Wed Oct 25 14:57:56 2000 Delivered-To: freebsd-chat@freebsd.org Received: from prism.flugsvamp.com (cb58709-a.mdsn1.wi.home.com [24.17.241.9]) by hub.freebsd.org (Postfix) with ESMTP id 3392837B4C5 for ; Wed, 25 Oct 2000 14:57:53 -0700 (PDT) Received: (from jlemon@localhost) by prism.flugsvamp.com (8.11.0/8.11.0) id e9PLuQ988412; Wed, 25 Oct 2000 16:56:26 -0500 (CDT) (envelope-from jlemon) Date: Wed, 25 Oct 2000 16:56:26 -0500 From: Jonathan Lemon To: Simon Kirby Cc: Jonathan Lemon , Dan Kegel , chat@freebsd.org, linux-kernel@vger.kernel.org Subject: Re: kqueue microbenchmark results Message-ID: <20001025165626.B87091@prism.flugsvamp.com> References: <20001024225637.A54554@prism.flugsvamp.com> <39F6655A.353FD236@alumni.caltech.edu> <20001025010246.B57913@prism.flugsvamp.com> <20001025112709.A1500@stormix.com> <20001025122307.B78130@prism.flugsvamp.com> <20001025114028.F12064@stormix.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Mailer: Mutt 1.0pre2i In-Reply-To: <20001025114028.F12064@stormix.com> Sender: owner-freebsd-chat@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org On Wed, Oct 25, 2000 at 11:40:28AM -0700, Simon Kirby wrote: > On Wed, Oct 25, 2000 at 12:23:07PM -0500, Jonathan Lemon wrote: > > > Consider a program which reads from point A, writes to point B. If > > the buffer associated with B fills up, then we don't want to continue > > reading from A. > > > > A/B may be network sockets, pipes, or ptys. > > Fine, but we can bind the event watching to the device or socket or pipe > that will clog up, right? In which case, we'll later get a write event > (just like with select()), and then once there is some progress you can > go back to read()ing from the original descriptor. This is even easier > than using select() because you don't have to take the descriptor out of > the read set and put it in the write set temporarily -- it will > automatically work that way. Yes, but with the above, you can't use get_event() as your main dispatching loop to do the read() call any more, since there may be no notifications pending in the queue. So you have to expand your main loop to include both get_event() as well as walk the "these descriptors may have partial data" list. Also, as Jamie pointed out, with kqueue/select you can do: kevent/read/write while with a pure edge-triggered scheme, you either must do: bind_event/read/.../read == 0/write Or maintain your own "this descriptor may have data" list. Also, consider the following scenario for the proposed get_event(): 1. packet arrives, queues an event. 2. user retrieves event. 3. second packet arrives, queues event again. 4. user reads() all data. Now, next time around the loop, we get a notification for an event when there is no data to read. The application now must be prepared to handle this case (meaning no blocking read() calls can be used). Also, what happens if the user closes the socket after step 4 above? The user now receives a notification for a fd which no longer exists, or possibly has been reused for another connection. This may or may not make a difference to the application, but it must be prepared to handle it anyway. I believe that Zack Brown ran into this problem with one of the webservers he was writing. > > You can find my paper at http://people.freebsd.org/~jlemon > > I'll go and read it now. :) The paper talks about some of the issues we have been discussing, as well as the design rationale behind kqueue. I'd be happy to answer any questions about the paper. -- Jonathan To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-chat" in the body of the message