From e74577120bb1e57857ba139dfc11f51f527d5899 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Sat, 18 Jun 2005 20:42:49 +0000 Subject: [PATCH] properly handle accept returning EAGAIN or EINTR --- library/unix/io.factor | 19 ++++++++---- library/unix/sockets.factor | 59 +++++++++++++++++++++---------------- 2 files changed, 47 insertions(+), 31 deletions(-) diff --git a/library/unix/io.factor b/library/unix/io.factor index 8d06792eef..f79f2ed4b7 100644 --- a/library/unix/io.factor +++ b/library/unix/io.factor @@ -75,8 +75,12 @@ M: port set-timeout ( timeout port -- ) : pending-error ( reader -- ) port-error throw ; -: postpone-error ( reader -- ) - err_no strerror swap set-port-error ; +: EAGAIN 35 ; +: EINTR 4 ; + +: postpone-error ( port -- ) + err_no dup EAGAIN = over EINTR = or + [ 2drop ] [ strerror swap set-port-error ] ifte ; ! Associates a port with a list of continuations waiting on the ! port to finish I/O @@ -116,14 +120,15 @@ GENERIC: task-container ( task -- vector ) port-cutoff dup 0 = not swap millis < and ; : handle-fd? ( fdset task -- ? ) - dup io-task-port timeout? - [ + dup io-task-port timeout? [ 2drop t ] [ io-task-fd swap 2dup bit-nth >r f -rot set-bit-nth r> ] ifte ; +: debug-out 14 getenv fwrite ; + : handle-fdset ( fdset tasks -- ) [ cdr tuck handle-fd? [ handle-fd ] [ drop ] ifte @@ -212,10 +217,12 @@ C: reader ( handle -- reader ) drop ] ifte t swap set-reader-ready? ; +: (refill) ( port -- n ) + >port< tuck dup buffer-end swap buffer-capacity read ; + : refill ( port -- ) dup buffer-length 0 = [ - >port< - tuck dup buffer-end swap buffer-capacity read + (refill) dup 0 >= [ swap n>buffer ] [ drop postpone-error ] ifte ] [ drop diff --git a/library/unix/sockets.factor b/library/unix/sockets.factor index 10e7212806..0afa69fdc2 100644 --- a/library/unix/sockets.factor +++ b/library/unix/sockets.factor @@ -49,12 +49,44 @@ USING: alien generic kernel math unix-internals ; dup 0 >= [ drop 1 listen ] [ ( fd n - n) nip ] ifte ] with-socket-fd ; +IN: streams + +C: client-stream ( host port fd -- stream ) + [ >r r> set-delegate ] keep + [ set-client-stream-port ] keep + [ set-client-stream-host ] keep ; + +: ( host port -- stream ) + #! Connect to a port number on a TCP/IP host. + client-socket ; + +TUPLE: server client ; + +C: server ( port -- server ) + #! Starts listening for TCP connections on localhost:port. + [ >r server-socket 0 r> set-delegate ] keep ; + +IN: io-internals +USE: unix-internals + TUPLE: accept-task ; C: accept-task ( port -- task ) [ >r r> set-delegate ] keep ; -M: accept-task do-io-task ( task -- ? ) drop t ; +: init-socket ( fd -- ) SOL_SOCKET SO_OOBINLINE sockopt ; + +: do-accept ( port sockaddr fd -- ) + [ + init-socket + dup sockaddr-in-addr inet-ntoa + swap sockaddr-in-port ntohs + ] keep swap set-server-client ; + +M: accept-task do-io-task ( task -- ? ) + io-task-port + over port-handle over "sockaddr-in" c-size accept + dup 0 >= [ do-accept t ] [ 2drop postpone-error f ] ifte ; M: accept-task task-container drop read-tasks get ; @@ -69,12 +101,6 @@ M: accept-task task-container drop read-tasks get ; HEX: ff bitand unparse % ] make-string ; -: do-accept ( fd -- fd host port ) - - [ "sockaddr-in" c-size accept dup io-error ] keep - dup sockaddr-in-addr inet-ntoa - swap sockaddr-in-port ntohs ; - : ( fd -- stream ) dup f ; @@ -83,23 +109,6 @@ M: accept-task task-container drop read-tasks get ; IN: streams -C: client-stream ( fd host port -- stream ) - [ set-client-stream-port ] keep - [ set-client-stream-host ] keep - [ - >r - dup SOL_SOCKET SO_OOBINLINE sockopt - r> set-delegate - ] keep ; - -: ( host port -- stream ) - #! Connect to a port number on a TCP/IP host. - client-socket ; - -: ( port -- server ) - #! Starts listening for TCP connections on localhost:port. - server-socket 0 ; - : accept ( server -- client ) #! Wait for a client connection. - dup wait-to-accept port-handle do-accept ; + dup wait-to-accept server-client ;