1 ! Copyright (C) 2004, 2008 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: alien.c-types kernel bit-arrays sequences assocs unix
4 math namespaces accessors math.order locals unix.time fry
5 io.ports io.backend.unix io.backend.unix.multiplexers ;
6 IN: io.backend.unix.multiplexers.select
8 TUPLE: select-mx < mx read-fdset write-fdset ;
10 ! Factor's bit-arrays are an array of bytes, OS X expects
11 ! FD_SET to be an array of cells, so we have to account for
12 ! byte order differences on big endian platforms
14 little-endian? [ BIN: 11000 bitxor ] unless ; inline
16 : <select-mx> ( -- mx )
18 FD_SETSIZE 8 * <bit-array> >>read-fdset
19 FD_SETSIZE 8 * <bit-array> >>write-fdset ;
21 : clear-nth ( n seq -- ? )
22 [ nth ] [ [ f ] 2dip set-nth ] 2bi ;
24 :: check-fd ( fd fdset mx quot -- )
25 fd munge fdset clear-nth [ fd mx quot call ] when ; inline
27 : check-fdset ( fds fdset mx quot -- )
28 [ check-fd ] 3curry each ; inline
30 : init-fdset ( fds fdset -- )
31 '[ t swap munge _ set-nth ] each ;
33 : read-fdset/tasks ( mx -- seq fdset )
34 [ reads>> keys ] [ read-fdset>> ] bi ;
36 : write-fdset/tasks ( mx -- seq fdset )
37 [ writes>> keys ] [ write-fdset>> ] bi ;
39 : max-fd ( assoc -- n )
40 dup assoc-empty? [ drop 0 ] [ keys supremum ] if ;
43 [ reads>> max-fd ] [ writes>> max-fd ] bi max 1 + ;
45 : init-fdsets ( mx -- nfds read write except )
47 [ read-fdset/tasks [ init-fdset ] keep ]
48 [ write-fdset/tasks [ init-fdset ] keep ] tri
51 M:: select-mx wait-for-events ( us mx -- )
53 [ init-fdsets us dup [ make-timeval ] when select multiplexer-error drop ]
54 [ [ read-fdset/tasks ] keep [ input-available ] check-fdset ]
55 [ [ write-fdset/tasks ] keep [ output-available ] check-fdset ]