properly handle accept returning EAGAIN or EINTR
parent
d39f686e3e
commit
e74577120b
|
@ -75,8 +75,12 @@ M: port set-timeout ( timeout port -- )
|
||||||
|
|
||||||
: pending-error ( reader -- ) port-error throw ;
|
: pending-error ( reader -- ) port-error throw ;
|
||||||
|
|
||||||
: postpone-error ( reader -- )
|
: EAGAIN 35 ;
|
||||||
err_no strerror swap set-port-error ;
|
: 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
|
! Associates a port with a list of continuations waiting on the
|
||||||
! port to finish I/O
|
! port to finish I/O
|
||||||
|
@ -116,14 +120,15 @@ GENERIC: task-container ( task -- vector )
|
||||||
port-cutoff dup 0 = not swap millis < and ;
|
port-cutoff dup 0 = not swap millis < and ;
|
||||||
|
|
||||||
: handle-fd? ( fdset task -- ? )
|
: handle-fd? ( fdset task -- ? )
|
||||||
dup io-task-port timeout?
|
dup io-task-port timeout? [
|
||||||
[
|
|
||||||
2drop t
|
2drop t
|
||||||
] [
|
] [
|
||||||
io-task-fd swap 2dup bit-nth
|
io-task-fd swap 2dup bit-nth
|
||||||
>r f -rot set-bit-nth r>
|
>r f -rot set-bit-nth r>
|
||||||
] ifte ;
|
] ifte ;
|
||||||
|
|
||||||
|
: debug-out 14 getenv fwrite ;
|
||||||
|
|
||||||
: handle-fdset ( fdset tasks -- )
|
: handle-fdset ( fdset tasks -- )
|
||||||
[
|
[
|
||||||
cdr tuck handle-fd? [ handle-fd ] [ drop ] ifte
|
cdr tuck handle-fd? [ handle-fd ] [ drop ] ifte
|
||||||
|
@ -212,10 +217,12 @@ C: reader ( handle -- reader )
|
||||||
drop
|
drop
|
||||||
] ifte t swap set-reader-ready? ;
|
] ifte t swap set-reader-ready? ;
|
||||||
|
|
||||||
|
: (refill) ( port -- n )
|
||||||
|
>port< tuck dup buffer-end swap buffer-capacity read ;
|
||||||
|
|
||||||
: refill ( port -- )
|
: refill ( port -- )
|
||||||
dup buffer-length 0 = [
|
dup buffer-length 0 = [
|
||||||
>port<
|
(refill)
|
||||||
tuck dup buffer-end swap buffer-capacity read
|
|
||||||
dup 0 >= [ swap n>buffer ] [ drop postpone-error ] ifte
|
dup 0 >= [ swap n>buffer ] [ drop postpone-error ] ifte
|
||||||
] [
|
] [
|
||||||
drop
|
drop
|
||||||
|
|
|
@ -49,12 +49,44 @@ USING: alien generic kernel math unix-internals ;
|
||||||
dup 0 >= [ drop 1 listen ] [ ( fd n - n) nip ] ifte
|
dup 0 >= [ drop 1 listen ] [ ( fd n - n) nip ] ifte
|
||||||
] with-socket-fd ;
|
] with-socket-fd ;
|
||||||
|
|
||||||
|
IN: streams
|
||||||
|
|
||||||
|
C: client-stream ( host port fd -- stream )
|
||||||
|
[ >r <socket-stream> r> set-delegate ] keep
|
||||||
|
[ set-client-stream-port ] keep
|
||||||
|
[ set-client-stream-host ] keep ;
|
||||||
|
|
||||||
|
: <client> ( host port -- stream )
|
||||||
|
#! Connect to a port number on a TCP/IP host.
|
||||||
|
client-socket <socket-stream> ;
|
||||||
|
|
||||||
|
TUPLE: server client ;
|
||||||
|
|
||||||
|
C: server ( port -- server )
|
||||||
|
#! Starts listening for TCP connections on localhost:port.
|
||||||
|
[ >r server-socket 0 <port> r> set-delegate ] keep ;
|
||||||
|
|
||||||
|
IN: io-internals
|
||||||
|
USE: unix-internals
|
||||||
|
|
||||||
TUPLE: accept-task ;
|
TUPLE: accept-task ;
|
||||||
|
|
||||||
C: accept-task ( port -- task )
|
C: accept-task ( port -- task )
|
||||||
[ >r <io-task> r> set-delegate ] keep ;
|
[ >r <io-task> 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 <client-stream> swap set-server-client ;
|
||||||
|
|
||||||
|
M: accept-task do-io-task ( task -- ? )
|
||||||
|
io-task-port <sockaddr-in>
|
||||||
|
over port-handle over "sockaddr-in" c-size <int> accept
|
||||||
|
dup 0 >= [ do-accept t ] [ 2drop postpone-error f ] ifte ;
|
||||||
|
|
||||||
M: accept-task task-container drop read-tasks get ;
|
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 %
|
HEX: ff bitand unparse %
|
||||||
] make-string ;
|
] make-string ;
|
||||||
|
|
||||||
: do-accept ( fd -- fd host port )
|
|
||||||
<sockaddr-in>
|
|
||||||
[ "sockaddr-in" c-size <int> accept dup io-error ] keep
|
|
||||||
dup sockaddr-in-addr inet-ntoa
|
|
||||||
swap sockaddr-in-port ntohs ;
|
|
||||||
|
|
||||||
: <socket-stream> ( fd -- stream )
|
: <socket-stream> ( fd -- stream )
|
||||||
dup f <fd-stream> ;
|
dup f <fd-stream> ;
|
||||||
|
|
||||||
|
@ -83,23 +109,6 @@ M: accept-task task-container drop read-tasks get ;
|
||||||
|
|
||||||
IN: streams
|
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
|
|
||||||
<socket-stream> r> set-delegate
|
|
||||||
] keep ;
|
|
||||||
|
|
||||||
: <client> ( host port -- stream )
|
|
||||||
#! Connect to a port number on a TCP/IP host.
|
|
||||||
client-socket <socket-stream> ;
|
|
||||||
|
|
||||||
: <server> ( port -- server )
|
|
||||||
#! Starts listening for TCP connections on localhost:port.
|
|
||||||
server-socket 0 <port> ;
|
|
||||||
|
|
||||||
: accept ( server -- client )
|
: accept ( server -- client )
|
||||||
#! Wait for a client connection.
|
#! Wait for a client connection.
|
||||||
dup wait-to-accept port-handle do-accept <client-stream> ;
|
dup wait-to-accept server-client ;
|
||||||
|
|
Loading…
Reference in New Issue