io.sockets: receive-unsafe and receive-into

Analogous to read-unsafe/read-into for streams (and thereby TCP sockets), provide receive-unsafe and receive-into words for datagram sockets that receive into a caller-supplied buffer.
db4
Joe Groff 2011-10-16 19:37:21 -07:00
parent 5443664df7
commit 20e49c273f
3 changed files with 51 additions and 37 deletions

View File

@ -4,11 +4,11 @@
USING: accessors alien.c-types alien.data alien.strings arrays
assocs byte-arrays classes classes.struct combinators
combinators.short-circuit continuations destructors fry generic
grouping init io.backend io.pathnames io.binary io.encodings
io.encodings.ascii io.encodings.binary io.ports
io.streams.duplex kernel math math.parser memoize namespaces
parser present sequences splitting strings summary system
vocabs.loader vocabs.parser ;
grouping init io.backend io.binary io.encodings
io.encodings.ascii io.encodings.binary io.pathnames io.ports
io.streams.duplex kernel libc locals math math.parser memoize
namespaces parser present sequences splitting strings summary
system unix.ffi values vocabs.loader vocabs.parser ;
IN: io.sockets
<< {
@ -286,7 +286,7 @@ TUPLE: raw-port < port addr ;
HOOK: (raw) io-backend ( addr -- raw )
HOOK: (receive) io-backend ( datagram -- packet addrspec )
HOOK: (receive) io-backend ( n buf datagram -- size addrspec )
ERROR: invalid-port object ;
@ -368,17 +368,37 @@ SYMBOL: remote-address
>>addr
] with-destructors ;
: receive ( datagram -- packet addrspec )
: receive-unsafe ( n buf datagram -- count addrspec )
check-receive
[ (receive) ] [ addr>> ] bi parse-sockaddr ;
[ (receive) ] [ addr>> ] bi parse-sockaddr ; inline
CONSTANT: datagram-size 65536
STRUCT: datagram-buf { buf uchar[datagram-size] } ;
:: receive ( datagram -- packet addrspec )
{ datagram-buf } [| buf |
datagram-size buf datagram
receive-unsafe :> ( count addrspec )
count [ f f ] [
buf swap memory>byte-array addrspec
] if-zero
] with-scoped-allocation ; inline
:: receive-into ( buf datagram -- buf-slice addrspec )
buf length :> n
n buf datagram receive-unsafe :> ( count addrspec )
count [ f f ] [ drop
buf count head-slice addrspec
] if-zero ; inline
: send ( packet addrspec datagram -- )
check-send (send) ;
check-send (send) ; inline
MEMO: ipv6-supported? ( -- ? )
[ "::1" 0 <inet6> binary <server> dispose t ] [ drop f ] recover ;
[ \ ipv6-supported? reset-memoized ] "io.sockets" add-startup-hook
[ \ ipv6-supported? reset-memoized ]
"io.sockets:ipv6-supported?" add-startup-hook
GENERIC: resolve-host ( addrspec -- seq )

View File

@ -125,29 +125,23 @@ M: unix (datagram)
M: unix (raw)
[ SOCK_RAW server-socket-fd ] with-destructors ;
SYMBOL: receive-buffer
CONSTANT: packet-size 65536
[ packet-size malloc &free receive-buffer set-global ] "io.sockets.unix" add-startup-hook
:: do-receive ( port -- packet sockaddr )
:: do-receive ( n buf port -- count sockaddr )
port addr>> empty-sockaddr/size :> ( sockaddr len )
port handle>> handle-fd ! s
receive-buffer get-global ! buf
packet-size ! nbytes
buf ! buf
n ! nbytes
0 ! flags
sockaddr ! from
len int <ref> ! fromlen
recvfrom dup 0 >=
[ receive-buffer get-global swap memory>byte-array sockaddr ]
[ drop f f ]
if ;
recvfrom sockaddr ; inline
M: unix (receive) ( datagram -- packet sockaddr )
dup do-receive dup [ [ drop ] 2dip ] [
2drop [ +input+ wait-for-port ] [ (receive) ] bi
] if ;
: (receive-loop) ( n buf datagram -- count sockaddr )
3dup do-receive over 0 > [ [ 3drop ] 2dip ] [
2drop [ +input+ wait-for-port ] [ (receive-loop) ] bi
] if ; inline recursive
M: unix (receive) ( n buf datagram -- count sockaddr )
(receive-loop) ;
:: do-send ( packet sockaddr len socket datagram -- )
socket handle-fd packet dup length 0 sockaddr len sendto
@ -162,7 +156,7 @@ M: unix (receive) ( datagram -- packet sockaddr )
(io-error)
] if
] if
] when ;
] when ; inline recursive
M: unix (send) ( packet addrspec datagram -- )
[ make-sockaddr/size ] [ [ handle>> ] keep ] bi* do-send ;

View File

@ -211,19 +211,19 @@ TUPLE: WSARecvFrom-args port
s lpBuffers dwBufferCount lpNumberOfBytesRecvd
lpFlags lpFrom lpFromLen lpOverlapped lpCompletionRoutine ;
: make-receive-buffer ( -- WSABUF )
: make-receive-buffer ( n buf -- WSABUF )
WSABUF malloc-struct &free
default-buffer-size get
[ >>len ] [ malloc &free >>buf ] bi ; inline
n >>len
buf >>buf ; inline
: <WSARecvFrom-args> ( datagram -- WSARecvFrom )
:: <WSARecvFrom-args> ( n buf datagram -- WSARecvFrom )
WSARecvFrom-args new
swap >>port
dup port>> handle>> handle>> >>s
dup port>> addr>> sockaddr-size
datagram >>port
datagram handle>> handle>> >>s
datagram addr>> sockaddr-size
[ malloc &free >>lpFrom ]
[ malloc-int &free >>lpFromLen ] bi
make-receive-buffer >>lpBuffers
n buf make-receive-buffer >>lpBuffers
1 >>dwBufferCount
0 malloc-int &free >>lpFlags
0 malloc-int &free >>lpNumberOfBytesRecvd
@ -251,7 +251,7 @@ TUPLE: WSARecvFrom-args port
tri memcpy
] bi ; inline
M: windows (receive) ( datagram -- packet addrspec )
M: windows (receive) ( n buf datagram -- packet addrspec )
[
<WSARecvFrom-args>
[ call-WSARecvFrom ]