From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: ludovic.courtes@laas.fr (Ludovic =?iso-8859-1?Q?Court=E8s?=) Newsgroups: gmane.lisp.guile.devel Subject: Re: Unbuffered socket I/O Date: Mon, 26 Feb 2007 15:07:43 +0100 Organization: LAAS-CNRS Message-ID: <877iu59fm8.fsf@laas.fr> References: <87mz34ol6r.fsf@laas.fr> <87abz13kxl.fsf@zip.com.au> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: sea.gmane.org 1172499399 24730 80.91.229.12 (26 Feb 2007 14:16:39 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Mon, 26 Feb 2007 14:16:39 +0000 (UTC) To: Guile-Devel Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Mon Feb 26 15:16:18 2007 Return-path: Envelope-to: guile-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1HLgWB-0001KG-D0 for guile-devel@m.gmane.org; Mon, 26 Feb 2007 15:07:55 +0100 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1HLgWA-0002vE-Sj for guile-devel@m.gmane.org; Mon, 26 Feb 2007 09:07:54 -0500 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1HLgW5-0002v7-ST for guile-devel@gnu.org; Mon, 26 Feb 2007 09:07:49 -0500 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1HLgW3-0002uv-CS for guile-devel@gnu.org; Mon, 26 Feb 2007 09:07:48 -0500 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1HLgW3-0002us-6s for guile-devel@gnu.org; Mon, 26 Feb 2007 09:07:47 -0500 Original-Received: from laas.laas.fr ([140.93.0.15]) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_3DES_EDE_CBC_SHA:24) (Exim 4.52) id 1HLgW2-0005Z8-II for guile-devel@gnu.org; Mon, 26 Feb 2007 09:07:46 -0500 Original-Received: from messiaen.laas.fr (messiaen [IPv6:2001:660:6602:0:230:65ff:fed4:9d20]) by laas.laas.fr (8.13.8/8.13.8) with SMTP id l1QE7i0j008433 for ; Mon, 26 Feb 2007 15:07:44 +0100 (MET) Original-Received: by messiaen.laas.fr (sSMTP sendmail emulation); Mon, 26 Feb 2007 15:07:44 +0100 X-URL: http://www.laas.fr/~lcourtes/ X-Revolutionary-Date: 8 =?iso-8859-1?Q?Vent=F4se?= an 215 de la =?iso-8859-1?Q?R=E9volution?= X-PGP-Key-ID: 0xEB1F5364 X-PGP-Key: http://www.laas.fr/~lcourtes/ludovic.asc X-PGP-Fingerprint: 821D 815D 902A 7EAB 5CEE D120 7FBA 3D4F EB1F 5364 X-OS: powerpc-unknown-linux-gnu Mail-Followup-To: Guile-Devel In-Reply-To: <87abz13kxl.fsf@zip.com.au> (Kevin Ryde's message of "Mon, 26 Feb 2007 09:57:10 +1100") User-Agent: Gnus/5.110006 (No Gnus v0.6) Emacs/21.4 (gnu/linux) X-Spam-Score: 0.306 () MAILTO_TO_SPAM_ADDR,NO_RELAYS X-Scanned-By: MIMEDefang at CNRS-LAAS on IPv6:2001:660:6602::2 X-detected-kernel: Solaris 10 (beta) X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Errors-To: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.devel:6565 Archived-At: --=-=-= Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by laas.laas.fr id l1QE7i0j008433 Hi, Kevin Ryde writes: > ludovic.courtes@laas.fr (Ludovic Court=E8s) writes: >> #define SCM_SOCK_FD_TO_PORT(fd) \ >> scm_fdes_to_port (fd, "r", sym_socket) > > That's an incompatible change, I think, since it can leave unflushed > data where previously it went straight out. Right. That's an incompatible change if the _output_ is buffered. Input can be buffered, though, without this being visible by users. Fortunately, port buffering doesn't have to be symmetrical (although the API allowing to do that is internal---actually, we might want to expose and document `scm_fport_buffer_add ()'). Thus, I propose the following change, where sockets are turned into ports whose output is left unbuffered and whose input is buffered. Again, this has no visible effect on user programs AFAICS. I tried it with TCP server-side sockets and the performance impact is _huge_. Actually, it seems even hard to write a TCP server without this because it takes so long to read a single octet that clients may time-out before the server is done receiving their request! (I observed this with RPC server/clients) BTW, do you know what the purpose of `fport_wait_for_input ()' is? It does nothing for O_NONBLOCK streams and waits for events otherwise. Since, for blocking streams, `read ()' does not return until either EOF is reached or at least one octet was read, `fport_wait_for_input ()' seems redundant. Thanks, Ludovic. --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename*=us-ascii''%2c%2csocket-buffering.diff Content-Description: Patch providing socket input buffering. --- orig/libguile/fports.c +++ mod/libguile/fports.c @@ -90,11 +90,11 @@ /* default buffer size, used if the O/S won't supply a value. */ static const size_t default_buffer_size = 1024; -/* create FPORT buffer with specified sizes (or -1 to use default size or - 0 for no buffer. */ -static void -scm_fport_buffer_add (SCM port, long read_size, int write_size) -#define FUNC_NAME "scm_fport_buffer_add" +/* Create FPORT buffer with specified sizes (or -1 to use default size or + 0 for no buffer). */ +void +scm_i_fport_buffer_add (SCM port, long read_size, long write_size) +#define FUNC_NAME "scm_i_fport_buffer_add" { scm_t_port *pt = SCM_PTAB_ENTRY (port); @@ -212,7 +212,7 @@ if (pt->write_buf != &pt->shortbuf) scm_gc_free (pt->write_buf, pt->write_buf_size, "port buffer"); - scm_fport_buffer_add (port, csize, csize); + scm_i_fport_buffer_add (port, csize, csize); return SCM_UNSPECIFIED; } #undef FUNC_NAME @@ -465,9 +465,9 @@ pt->rw_random = SCM_FDES_RANDOM_P (fdes); SCM_SETSTREAM (port, fp); if (mode_bits & SCM_BUF0) - scm_fport_buffer_add (port, 0, 0); + scm_i_fport_buffer_add (port, 0, 0); else - scm_fport_buffer_add (port, -1, -1); + scm_i_fport_buffer_add (port, -1, -1); } SCM_SET_FILENAME (port, name); scm_i_pthread_mutex_unlock (&scm_i_port_table_mutex); --- orig/libguile/fports.h +++ mod/libguile/fports.h @@ -60,7 +60,8 @@ SCM_API SCM scm_i_fdes_to_port (int fdes, long mode_bits, SCM name); SCM_API int scm_i_fport_truncate (SCM, SCM); SCM_API SCM scm_i_fport_seek (SCM, SCM, int); - +SCM_API void scm_i_fport_buffer_add (SCM port, long read_size, + long write_size); #endif /* SCM_FPORTS_H */ --- orig/libguile/socket.c +++ mod/libguile/socket.c @@ -403,9 +403,26 @@ #endif /* HAVE_IPV6 */ + +/* Sockets. */ + SCM_SYMBOL (sym_socket, "socket"); -#define SCM_SOCK_FD_TO_PORT(fd) scm_fdes_to_port (fd, "r+0", sym_socket) +/* Size of the input buffer of socket ports. */ +#define SCM_SOCKET_INPUT_BUFFER_SIZE 4096 + + +/* Return a socket with buffered input and unbufferred output. */ +static inline SCM +socket_to_port (int fd) +{ + SCM port; + + port = scm_fdes_to_port (fd, "r+0", sym_socket); + scm_i_fport_buffer_add (port, SCM_SOCKET_INPUT_BUFFER_SIZE, 0); + + return port; +} SCM_DEFINE (scm_socket, "socket", 3, 0, 0, (SCM family, SCM style, SCM proto), @@ -429,7 +446,7 @@ scm_to_int (proto)); if (fd == -1) SCM_SYSERROR; - return SCM_SOCK_FD_TO_PORT (fd); + return socket_to_port (fd); } #undef FUNC_NAME @@ -451,7 +468,7 @@ if (socketpair (fam, scm_to_int (style), scm_to_int (proto), fd) == -1) SCM_SYSERROR; - return scm_cons (SCM_SOCK_FD_TO_PORT (fd[0]), SCM_SOCK_FD_TO_PORT (fd[1])); + return scm_cons (socket_to_port (fd[0]), socket_to_port (fd[1])); } #undef FUNC_NAME #endif @@ -1312,7 +1329,7 @@ newfd = accept (fd, addr, &addr_size); if (newfd == -1) SCM_SYSERROR; - newsock = SCM_SOCK_FD_TO_PORT (newfd); + newsock = socket_to_port (newfd); address = _scm_from_sockaddr (addr, addr_size, FUNC_NAME); return scm_cons (newsock, address); } --=-=-= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://lists.gnu.org/mailman/listinfo/guile-devel --=-=-=--