]> gitweb.factorcode.org Git - factor.git/commitdiff
io.sockets: receive-unsafe and receive-into
authorJoe Groff <arcata@gmail.com>
Mon, 17 Oct 2011 02:37:21 +0000 (19:37 -0700)
committerJoe Groff <arcata@gmail.com>
Tue, 18 Oct 2011 04:23:11 +0000 (21:23 -0700)
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.

basis/io/sockets/sockets.factor
basis/io/sockets/unix/unix.factor
basis/io/sockets/windows/windows.factor

index 2da840833cb1e6fe1e824520d24e31b8c3349545..0828d11b23c8c59139c8d51c77944b0be5bd0f24 100644 (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 )
 
index 3f91c0e8b6e1afe3f152170f0f872720258a810a..fc59b8ce510892f467ac41ec61dce7f5471fc548 100644 (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
+
+: (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) ( datagram -- packet sockaddr )
-    dup do-receive dup [ [ drop ] 2dip ] [
-        2drop [ +input+ wait-for-port ] [ (receive) ] bi
-    ] if ;
+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 ;
index 359826003f3b6defc70f9de7fe7aefcaf33bce25..1b270e6e19b058e851706e41d4d1613dada745e3 100755 (executable)
@@ -211,19 +211,19 @@ TUPLE: WSARecvFrom-args port
        s lpBuffers dwBufferCount lpNumberOfBytesRecvd\r
        lpFlags lpFrom lpFromLen lpOverlapped lpCompletionRoutine ;\r
 \r
-: make-receive-buffer ( -- WSABUF )\r
+: make-receive-buffer ( n buf -- WSABUF )\r
     WSABUF malloc-struct &free\r
-        default-buffer-size get\r
-        [ >>len ] [ malloc &free >>buf ] bi ; inline\r
+        n >>len\r
+        buf >>buf ; inline\r
 \r
-: <WSARecvFrom-args> ( datagram -- WSARecvFrom )\r
+:: <WSARecvFrom-args> ( n buf datagram -- WSARecvFrom )\r
     WSARecvFrom-args new\r
-        swap >>port\r
-        dup port>> handle>> handle>> >>s\r
-        dup port>> addr>> sockaddr-size\r
+        datagram >>port\r
+        datagram handle>> handle>> >>s\r
+        datagram addr>> sockaddr-size\r
             [ malloc &free >>lpFrom ]\r
             [ malloc-int &free >>lpFromLen ] bi\r
-        make-receive-buffer >>lpBuffers\r
+        n buf make-receive-buffer >>lpBuffers\r
         1 >>dwBufferCount\r
         0 malloc-int &free >>lpFlags\r
         0 malloc-int &free >>lpNumberOfBytesRecvd\r
@@ -251,7 +251,7 @@ TUPLE: WSARecvFrom-args port
         tri memcpy\r
     ] bi ; inline\r
 \r
-M: windows (receive) ( datagram -- packet addrspec )\r
+M: windows (receive) ( n buf datagram -- packet addrspec )\r
     [\r
         <WSARecvFrom-args>\r
         [ call-WSARecvFrom ]\r