From owner-freebsd-hackers Wed Feb 13 2: 1:20 2002 Delivered-To: freebsd-hackers@freebsd.org Received: from mail.nsu.ru (mx.nsu.ru [193.124.215.71]) by hub.freebsd.org (Postfix) with ESMTP id B165937B416 for ; Wed, 13 Feb 2002 02:01:13 -0800 (PST) Received: from regency.nsu.ru ([193.124.210.26] helo=cytherea.weblab.nsu.ru) by mail.nsu.ru with esmtp (Exim 3.20 #1) id 16awDM-0006TX-00; Wed, 13 Feb 2002 16:00:36 +0600 Received: (from danfe@localhost) by cytherea.weblab.nsu.ru (8.11.6/8.11.6) id g1DA0EL05182; Wed, 13 Feb 2002 16:00:14 +0600 (NOVT) (envelope-from danfe) Date: Wed, 13 Feb 2002 16:00:14 +0600 From: Alexey Dokuchaev To: thttpd@acme.com Cc: hackers@freebsd.org Subject: THTTPD web server: problems with KQUEUE on FreeBSD 4.5-STABLE Message-ID: <20020213160014.A97359@cytherea.weblab.nsu.ru> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5.1i Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG Hello! I've been using thttpd-2.22beta4 (www/thttpd) for about two weeks, and it has been serving me greatly so far, except for one day... I've been looking through http.log, and started to notice strange messages: 123.124.125.51 - - [13/Feb/2002:14:56:26 +0600] "GET /123.124.210.52/top100.jpg HTTP/1.1" 200 0 "http://123.124.125.52/" "Mozilla/4.0 (compatible; MSIE 5.01; Wi ndows NT 5.0)" 123.124.125.51 - - [13/Feb/2002:14:56:29 +0600] "GET /123.124.210.52/wolfenpsd_b utton.gif HTTP/1.1" 200 0 "http://123.124.125.52/" "Mozilla/4.0 (compatible; MSI E 5.01; Windows NT 5.0)" 123.124.125.51 - - [13/Feb/2002:14:56:40 +0600] "GET /123.124.210.52/wolfstat_bu tton.gif HTTP/1.1" 200 0 "http://123.124.125.52/" "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)" 123.124.125.51 - - [13/Feb/2002:14:56:40 +0600] "GET /123.124.210.52/wolfmod.jpg HTTP/1.1" 200 0 "http://123.124.125.52/" "Mozilla/4.0 (compatible; MSIE 5.01; W indows NT 5.0)" As you can notice, server says "200 OK", but returns contents of length of 0! That's very strange. I've started to explore this issue, and found out that things break around here (thttpd.c, lines 580-597): /* Find the connections that need servicing. */ for ( ridx = 0; ridx < num_ready; ++ridx ) { c = (connecttab*) fdwatch_get_client_data( ridx ); if ( c == (connecttab*) 0 ) continue; hc = c->hc; if ( ! fdwatch_check_fd( hc->conn_fd ) ) { /* Something went wrong. */ printf("!!!!!!!!!!!!!!!!!!\n"); clear_connection( c, &tv ); } else switch ( c->conn_state ) { case CNST_READING: handle_read( c, &tv ); break; case CNST_SENDING: handle_send( c, &tv ); break; case CNST_LINGERING: handle_linger( c, &tv ); break; } } I've marked with "!!!!!!!!!!!!!!!!!" the error-place. More over, if, say, server must serve 10 objects, and 2 will fail, there be 10 calls of handle_read(), and only 8 of handle_send(), that is, that handle_read() still gets called, even if fdwatch_check_fd() returned an error. I decided not to run through all of fdwatch.c stuff, and neither through FreeBSD sources, since I'm not too familiar with kqread mechanism. What I did next, I've simply removed -DHAVE_KQUEUE from Makefile, and recompiled the whole thing. The problem dissappreared! I haven't checked the -DHAVE_POLL, but it seems that thttpd feels much better with poll()'ing than with kqread()'ing (as seen in top(1)). I still wonder, whether this problem occurs because of how thttpd does things, or how FreeBSD implements kqueue stuff, however, I am not sure that I will have enough time to dig deep into this. Right now I'm pretty happy with the fact that I got thttpd working again, and those "200 0" messages are no longer in my logs. However, it is still an issue to worry about, I believe, and I will be a lot more happy if my experience helps either folks to find and fix some probable bugs (if any) in their excellent software. And one more question: out of kqread()/poll()/select() methods, which one is more likely to perform better, both under normal server access, and under heavy load? This is pretty important for me to choose the right method of doing the non-blocking I/O, and, even in case I cannot use kqueue, I am still curious which one is more preferrable for a webserver to use, poll() or select() ? Thank you very much for your time and concern. -- Sincerely, Alexey Dokuchaev To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message