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