]> gitweb.factorcode.org Git - factor.git/blob - basis/io/unix/select/select.factor
f0547da10e92560b13214f3c2bf6ec9490f649a9
[factor.git] / basis / io / unix / select / select.factor
1 ! Copyright (C) 2004, 2008 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: alien.c-types kernel io.ports io.unix.backend
4 bit-arrays sequences assocs unix math namespaces structs
5 accessors math.order locals ;
6 IN: io.unix.select
7
8 TUPLE: select-mx < mx read-fdset write-fdset ;
9
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
13 : munge ( i -- i' )
14     little-endian? [ BIN: 11000 bitxor ] unless ; inline
15
16 : <select-mx> ( -- mx )
17     select-mx new-mx
18         FD_SETSIZE 8 * <bit-array> >>read-fdset
19         FD_SETSIZE 8 * <bit-array> >>write-fdset ;
20
21 : clear-nth ( n seq -- ? )
22     [ nth ] [ f -rot set-nth ] 2bi ;
23
24 :: check-fd ( fd fdset mx quot -- )
25     fd munge fdset clear-nth [ fd mx quot call ] when ; inline
26
27 : check-fdset ( fds fdset mx quot -- )
28     [ check-fd ] 3curry each ; inline
29
30 : init-fdset ( fds fdset -- )
31     [ >r t swap munge r> set-nth ] curry each ;
32
33 : read-fdset/tasks ( mx -- seq fdset )
34     [ reads>> keys ] [ read-fdset>> ] bi ;
35
36 : write-fdset/tasks ( mx -- seq fdset )
37     [ writes>> keys ] [ write-fdset>> ] bi ;
38
39 : max-fd ( assoc -- n )
40     dup assoc-empty? [ drop 0 ] [ keys supremum ] if ;
41
42 : num-fds ( mx -- n )
43     [ reads>> max-fd ] [ writes>> max-fd ] bi max 1+ ;
44
45 : init-fdsets ( mx -- nfds read write except )
46     [ num-fds ]
47     [ read-fdset/tasks [ init-fdset ] [ underlying>> ] bi ]
48     [ write-fdset/tasks [ init-fdset ] [ underlying>> ] bi ] tri
49     f ;
50
51 M:: select-mx wait-for-events ( ms mx -- )
52     mx
53     [ init-fdsets ms dup [ make-timeval ] when select multiplexer-error ]
54     [ [ read-fdset/tasks ] keep [ input-available ] check-fdset ]
55     [ [ write-fdset/tasks ] keep [ output-available ] check-fdset ]
56     tri ;