Hi, Kevin Ryde <[EMAIL PROTECTED]> writes:
> [EMAIL PROTECTED] (Ludovic Courtès) 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.
--- 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); }
_______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://lists.gnu.org/mailman/listinfo/guile-devel