I/O cleanups
parent
feb4e8df9e
commit
c1963dd4ab
extra/io
nonblocking
sniffer/bsd
unix
windows
ce/sockets
nt/sockets
|
@ -55,7 +55,7 @@ HELP: init-handle
|
|||
{ $contract "Prepares a native handle for use by the port; called by " { $link <port> } "." } ;
|
||||
|
||||
HELP: <port>
|
||||
{ $values { "handle" "a native handle identifying an I/O resource" } { "buffer" "a " { $link buffer } " or " { $link f } } { "port" "a new " { $link port } } }
|
||||
{ $values { "handle" "a native handle identifying an I/O resource" } { "buffer" "a " { $link buffer } " or " { $link f } } { "type" symbol } { "port" "a new " { $link port } } }
|
||||
{ $description "Creates a new " { $link port } " using the specified native handle and I/O buffer." }
|
||||
$low-level-note ;
|
||||
|
||||
|
|
|
@ -12,38 +12,36 @@ SYMBOL: default-buffer-size
|
|||
! Common delegate of native stream readers and writers
|
||||
TUPLE: port handle error timeout cutoff type eof? ;
|
||||
|
||||
SYMBOL: input
|
||||
SYMBOL: output
|
||||
SYMBOL: closed
|
||||
|
||||
PREDICATE: port input-port port-type input eq? ;
|
||||
PREDICATE: port output-port port-type output eq? ;
|
||||
PREDICATE: port input-port port-type input-port eq? ;
|
||||
PREDICATE: port output-port port-type output-port eq? ;
|
||||
|
||||
GENERIC: init-handle ( handle -- )
|
||||
GENERIC: close-handle ( handle -- )
|
||||
|
||||
: <port> ( handle buffer -- port )
|
||||
over init-handle
|
||||
: <port> ( handle buffer type -- port )
|
||||
pick init-handle
|
||||
0 0 {
|
||||
set-port-handle
|
||||
set-delegate
|
||||
set-port-type
|
||||
set-port-timeout
|
||||
set-port-cutoff
|
||||
} port construct ;
|
||||
|
||||
: <buffered-port> ( handle -- port )
|
||||
default-buffer-size get <buffer> <port> ;
|
||||
: <buffered-port> ( handle type -- port )
|
||||
default-buffer-size get <buffer> swap <port> ;
|
||||
|
||||
: <reader> ( handle -- stream )
|
||||
<buffered-port> input over set-port-type <line-reader> ;
|
||||
input-port <buffered-port> <line-reader> ;
|
||||
|
||||
: <writer> ( handle -- stream )
|
||||
<buffered-port> output over set-port-type <plain-writer> ;
|
||||
output-port <buffered-port> <plain-writer> ;
|
||||
|
||||
: handle>duplex-stream ( in-handle out-handle -- stream )
|
||||
<writer>
|
||||
[ >r <reader> r> <duplex-stream> ]
|
||||
[ ] [ stream-close ]
|
||||
[ >r <reader> r> <duplex-stream> ] [ ] [ stream-close ]
|
||||
cleanup ;
|
||||
|
||||
: touch-port ( port -- )
|
||||
|
@ -170,8 +168,8 @@ M: port stream-close
|
|||
|
||||
TUPLE: server-port addr client ;
|
||||
|
||||
: <server-port> ( port addr -- server )
|
||||
server-port pick set-port-type
|
||||
: <server-port> ( handle addr -- server )
|
||||
>r f server-port <port> r>
|
||||
{ set-delegate set-server-port-addr }
|
||||
server-port construct ;
|
||||
|
||||
|
@ -180,8 +178,8 @@ TUPLE: server-port addr client ;
|
|||
|
||||
TUPLE: datagram-port addr packet packet-addr ;
|
||||
|
||||
: <datagram-port> ( port addr -- datagram )
|
||||
datagram-port pick set-port-type
|
||||
: <datagram-port> ( handle addr -- datagram )
|
||||
>r f datagram-port <port> r>
|
||||
{ set-delegate set-datagram-port-addr }
|
||||
datagram-port construct ;
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ M: unix-io <sniffer> ( obj -- sniffer )
|
|||
] keep
|
||||
dupd sniffer-spec-ifname ioctl-sniffer-fd
|
||||
dup make-ioctl-buffer
|
||||
<port> input over set-port-type <line-reader>
|
||||
input-port <port> <line-reader>
|
||||
\ sniffer construct-delegate
|
||||
] with-destructors ;
|
||||
|
||||
|
|
|
@ -18,19 +18,33 @@ TUPLE: io-task port callbacks ;
|
|||
>r 1vector io-task construct-boa r> construct-delegate ;
|
||||
inline
|
||||
|
||||
TUPLE: input-task ;
|
||||
|
||||
: <input-task> ( port continuation class -- task )
|
||||
>r input-task <io-task> r> construct-delegate ; inline
|
||||
|
||||
TUPLE: output-task ;
|
||||
|
||||
: <output-task> ( port continuation class -- task )
|
||||
>r output-task <io-task> r> construct-delegate ; inline
|
||||
|
||||
GENERIC: do-io-task ( task -- ? )
|
||||
GENERIC: io-task-container ( mx task -- hashtable )
|
||||
|
||||
! I/O multiplexers
|
||||
TUPLE: mx fd reads writes ;
|
||||
|
||||
M: input-task io-task-container drop mx-reads ;
|
||||
|
||||
M: output-task io-task-container drop mx-writes ;
|
||||
|
||||
: <mx> ( -- mx ) f H{ } clone H{ } clone mx construct-boa ;
|
||||
|
||||
: construct-mx ( class -- obj ) <mx> swap construct-delegate ;
|
||||
|
||||
GENERIC: register-io-task ( task mx -- )
|
||||
GENERIC: unregister-io-task ( task mx -- )
|
||||
GENERIC: unix-io-multiplex ( ms mx -- )
|
||||
GENERIC: wait-for-events ( ms mx -- )
|
||||
|
||||
: fd/container ( task mx -- task fd container )
|
||||
over io-task-container >r dup io-task-fd r> ; inline
|
||||
|
@ -112,14 +126,12 @@ M: integer close-handle ( fd -- )
|
|||
TUPLE: read-task ;
|
||||
|
||||
: <read-task> ( port continuation -- task )
|
||||
read-task <io-task> ;
|
||||
read-task <input-task> ;
|
||||
|
||||
M: read-task do-io-task
|
||||
io-task-port dup refill
|
||||
[ [ reader-eof ] [ drop ] if ] keep ;
|
||||
|
||||
M: read-task io-task-container drop mx-reads ;
|
||||
|
||||
M: input-port (wait-to-read)
|
||||
[ <read-task> add-io-task stop ] callcc0 pending-error ;
|
||||
|
||||
|
@ -131,14 +143,12 @@ M: input-port (wait-to-read)
|
|||
TUPLE: write-task ;
|
||||
|
||||
: <write-task> ( port continuation -- task )
|
||||
write-task <io-task> ;
|
||||
write-task <output-task> ;
|
||||
|
||||
M: write-task do-io-task
|
||||
io-task-port dup buffer-empty? over port-error or
|
||||
[ 0 swap buffer-reset t ] [ write-step ] if ;
|
||||
|
||||
M: write-task io-task-container drop mx-writes ;
|
||||
|
||||
: add-write-io-task ( port continuation -- )
|
||||
over port-handle mx get-global mx-writes at*
|
||||
[ io-task-callbacks push drop ]
|
||||
|
@ -151,7 +161,7 @@ M: port port-flush ( port -- )
|
|||
dup buffer-empty? [ drop ] [ (wait-to-write) ] if ;
|
||||
|
||||
M: unix-io io-multiplex ( ms -- )
|
||||
mx get-global unix-io-multiplex ;
|
||||
mx get-global wait-for-events ;
|
||||
|
||||
M: unix-io init-stdio ( -- )
|
||||
0 1 handle>duplex-stream io:stdio set-global
|
||||
|
@ -161,8 +171,7 @@ M: unix-io init-stdio ( -- )
|
|||
TUPLE: mx-port mx ;
|
||||
|
||||
: <mx-port> ( mx -- port )
|
||||
dup mx-fd f <port>
|
||||
mx-port over set-port-type
|
||||
dup mx-fd f mx-port <port>
|
||||
{ set-mx-port-mx set-delegate } mx-port construct ;
|
||||
|
||||
TUPLE: mx-task ;
|
||||
|
@ -171,7 +180,7 @@ TUPLE: mx-task ;
|
|||
f io-task construct-boa mx-task construct-delegate ;
|
||||
|
||||
M: mx-task do-io-task
|
||||
io-task-port mx-port-mx 0 swap unix-io-multiplex f ;
|
||||
io-task-port mx-port-mx 0 swap wait-for-events f ;
|
||||
|
||||
: multiplexer-error ( n -- )
|
||||
0 < [ err_no ignorable-error? [ (io-error) ] unless ] when ;
|
||||
|
|
|
@ -16,19 +16,15 @@ TUPLE: epoll-mx events ;
|
|||
max-events epoll_create dup io-error over set-mx-fd
|
||||
max-events "epoll-event" <c-array> over set-epoll-mx-events ;
|
||||
|
||||
: io-task-filter ( task -- n )
|
||||
class {
|
||||
{ read-task [ EVFILT_READ ] }
|
||||
{ accept-task [ EVFILT_READ ] }
|
||||
{ receive-task [ EVFILT_READ ] }
|
||||
{ write-task [ EVFILT_WRITE ] }
|
||||
{ connect-task [ EVFILT_WRITE ] }
|
||||
{ send-task [ EVFILT_WRITE ] }
|
||||
} case ;
|
||||
GENERIC: io-task-events ( task -- n )
|
||||
|
||||
M: input-task drop EPOLLIN ;
|
||||
|
||||
M: output-task drop EPOLLOUT ;
|
||||
|
||||
: make-event ( task -- event )
|
||||
"epoll-event" <c-object>
|
||||
tuck set-epoll-event-events
|
||||
over io-task-events over set-epoll-event-events
|
||||
over io-task-fd over set-epoll-fd ;
|
||||
|
||||
: do-epoll-ctl ( task mx what -- )
|
||||
|
@ -57,5 +53,5 @@ M: epoll-mx unregister-io-task ( task mx -- )
|
|||
: handle-events ( mx n -- )
|
||||
[ over epoll-mx-events kevent-nth handle-kevent ] with each ;
|
||||
|
||||
M: epoll-mx unix-io-multiplex ( ms mx -- )
|
||||
M: epoll-mx wait-for-events ( ms mx -- )
|
||||
dup rot wait-kevent handle-kevents ;
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
! Copyright (C) 2008 Slava Pestov.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: alien.c-types kernel io.nonblocking io.unix.backend
|
||||
io.unix.sockets sequences assocs unix unix.kqueue unix.process
|
||||
math namespaces classes combinators threads vectors ;
|
||||
sequences assocs unix unix.kqueue unix.process math namespaces
|
||||
combinators threads vectors ;
|
||||
IN: io.unix.kqueue
|
||||
|
||||
TUPLE: kqueue-mx events processes ;
|
||||
|
@ -18,15 +18,11 @@ TUPLE: kqueue-mx events processes ;
|
|||
H{ } clone over set-kqueue-mx-processes
|
||||
max-events "kevent" <c-array> over set-kqueue-mx-events ;
|
||||
|
||||
: io-task-filter ( task -- n )
|
||||
class {
|
||||
{ read-task [ EVFILT_READ ] }
|
||||
{ accept-task [ EVFILT_READ ] }
|
||||
{ receive-task [ EVFILT_READ ] }
|
||||
{ write-task [ EVFILT_WRITE ] }
|
||||
{ connect-task [ EVFILT_WRITE ] }
|
||||
{ send-task [ EVFILT_WRITE ] }
|
||||
} case ;
|
||||
GENERIC: io-task-filter ( task -- n )
|
||||
|
||||
M: input-task io-task-filter drop EVFILT_READ ;
|
||||
|
||||
M: output-task io-task-filter drop EVFILT_WRITE ;
|
||||
|
||||
: make-kevent ( task flags -- event )
|
||||
"kevent" <c-object>
|
||||
|
@ -70,7 +66,7 @@ M: kqueue-mx unregister-io-task ( task mx -- )
|
|||
: handle-kevents ( mx n -- )
|
||||
[ over kqueue-mx-events kevent-nth handle-kevent ] with each ;
|
||||
|
||||
M: kqueue-mx unix-io-multiplex ( ms mx -- )
|
||||
M: kqueue-mx wait-for-events ( ms mx -- )
|
||||
swap make-timespec dupd wait-kevent handle-kevents ;
|
||||
|
||||
: make-proc-kevent ( pid -- kevent )
|
||||
|
|
|
@ -40,7 +40,7 @@ TUPLE: select-mx read-fdset write-fdset ;
|
|||
write-fdset/tasks tuck init-fdset
|
||||
f ;
|
||||
|
||||
M: select-mx unix-io-multiplex ( ms mx -- )
|
||||
M: select-mx wait-for-events ( ms mx -- )
|
||||
swap >r FD_SETSIZE over init-fdsets r> make-timeval
|
||||
select multiplexer-error
|
||||
dup read-fdset/tasks pick handle-fdset
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
! Copyright (C) 2004, 2007 Slava Pestov, Ivan Tikhonov.
|
||||
! Copyright (C) 2004, 2008 Slava Pestov, Ivan Tikhonov.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
|
||||
! We need to fiddle with the exact search order here, since
|
||||
|
@ -34,14 +34,12 @@ M: unix-io addrinfo-error ( n -- )
|
|||
TUPLE: connect-task ;
|
||||
|
||||
: <connect-task> ( port continuation -- task )
|
||||
connect-task <io-task> ;
|
||||
connect-task <output-task> ;
|
||||
|
||||
M: connect-task do-io-task
|
||||
io-task-port dup port-handle f 0 write
|
||||
0 < [ defer-error ] [ drop t ] if ;
|
||||
|
||||
M: connect-task io-task-container drop mx-writes ;
|
||||
|
||||
: wait-to-connect ( port -- )
|
||||
[ <connect-task> add-io-task stop ] callcc0 drop ;
|
||||
|
||||
|
@ -68,9 +66,7 @@ USE: unix
|
|||
TUPLE: accept-task ;
|
||||
|
||||
: <accept-task> ( port continuation -- task )
|
||||
accept-task <io-task> ;
|
||||
|
||||
M: accept-task io-task-container drop mx-reads ;
|
||||
accept-task <input-task> ;
|
||||
|
||||
: accept-sockaddr ( port -- fd sockaddr )
|
||||
dup port-handle swap server-port-addr sockaddr-type
|
||||
|
@ -101,7 +97,6 @@ M: unix-io <server> ( addrspec -- stream )
|
|||
[
|
||||
SOCK_STREAM server-fd
|
||||
dup 10 listen zero? [ dup close (io-error) ] unless
|
||||
f <port>
|
||||
] keep <server-port> ;
|
||||
|
||||
M: unix-io accept ( server -- client )
|
||||
|
@ -113,7 +108,7 @@ M: unix-io accept ( server -- client )
|
|||
|
||||
! Datagram sockets - UDP and Unix domain
|
||||
M: unix-io <datagram>
|
||||
[ SOCK_DGRAM server-fd f <port> ] keep <datagram-port> ;
|
||||
[ SOCK_DGRAM server-fd ] keep <datagram-port> ;
|
||||
|
||||
SYMBOL: receive-buffer
|
||||
|
||||
|
@ -139,7 +134,7 @@ packet-size <byte-array> receive-buffer set-global
|
|||
TUPLE: receive-task ;
|
||||
|
||||
: <receive-task> ( stream continuation -- task )
|
||||
receive-task <io-task> ;
|
||||
receive-task <input-task> ;
|
||||
|
||||
M: receive-task do-io-task
|
||||
io-task-port
|
||||
|
@ -152,8 +147,6 @@ M: receive-task do-io-task
|
|||
2drop defer-error
|
||||
] if ;
|
||||
|
||||
M: receive-task io-task-container drop mx-reads ;
|
||||
|
||||
: wait-receive ( stream -- )
|
||||
[ <receive-task> add-io-task stop ] callcc0 drop ;
|
||||
|
||||
|
@ -170,7 +163,7 @@ M: unix-io receive ( datagram -- packet addrspec )
|
|||
TUPLE: send-task packet sockaddr len ;
|
||||
|
||||
: <send-task> ( packet sockaddr len stream continuation -- task )
|
||||
send-task <io-task> [
|
||||
send-task <output-task> [
|
||||
{
|
||||
set-send-task-packet
|
||||
set-send-task-sockaddr
|
||||
|
@ -185,8 +178,6 @@ M: send-task do-io-task
|
|||
[ send-task-len do-send ] keep
|
||||
swap 0 < [ io-task-port defer-error ] [ drop t ] if ;
|
||||
|
||||
M: send-task io-task-container drop mx-writes ;
|
||||
|
||||
: wait-send ( packet sockaddr len stream -- )
|
||||
[ <send-task> add-io-task stop ] callcc0 2drop 2drop ;
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ M: windows-ce-io <server> ( addrspec -- duplex-stream )
|
|||
[
|
||||
windows.winsock:SOCK_STREAM server-fd
|
||||
dup listen-on-socket
|
||||
<win32-socket> f <port>
|
||||
<win32-socket>
|
||||
] keep <server-port> ;
|
||||
|
||||
M: windows-ce-io accept ( server -- client )
|
||||
|
@ -58,7 +58,7 @@ M: windows-ce-io accept ( server -- client )
|
|||
|
||||
M: windows-ce-io <datagram> ( addrspec -- datagram )
|
||||
[
|
||||
windows.winsock:SOCK_DGRAM server-fd <win32-socket> f <port>
|
||||
windows.winsock:SOCK_DGRAM server-fd <win32-socket>
|
||||
] keep <datagram-port> ;
|
||||
|
||||
: packet-size 65536 ; inline
|
||||
|
|
|
@ -149,7 +149,7 @@ M: windows-nt-io <server> ( addrspec -- server )
|
|||
[
|
||||
SOCK_STREAM server-fd dup listen-on-socket
|
||||
dup add-completion
|
||||
<win32-socket> f <port>
|
||||
<win32-socket>
|
||||
] keep <server-port>
|
||||
] with-destructors ;
|
||||
|
||||
|
@ -158,7 +158,7 @@ M: windows-nt-io <datagram> ( addrspec -- datagram )
|
|||
[
|
||||
SOCK_DGRAM server-fd
|
||||
dup add-completion
|
||||
<win32-socket> f <port>
|
||||
<win32-socket>
|
||||
] keep <datagram-port>
|
||||
] with-destructors ;
|
||||
|
||||
|
|
Loading…
Reference in New Issue