1 ! Copyright (C) 2008 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors alien.c-types combinators destructors
4 io.backend.unix kernel math.bitwise sequences struct-arrays unix
5 unix.kqueue unix.time assocs io.backend.unix.multiplexers
7 IN: io.backend.unix.multiplexers.kqueue
9 TUPLE: kqueue-mx < mx events ;
11 ! We read up to 256 events at a time. This is an arbitrary
13 CONSTANT: max-events 256
15 : <kqueue-mx> ( -- mx )
17 kqueue dup io-error >>fd
18 max-events \ kevent <struct-array> >>events ;
20 M: kqueue-mx dispose* fd>> close-file ;
22 : make-kevent ( fd filter flags -- event )
28 : register-kevent ( kevent mx -- )
29 fd>> swap 1 f 0 f kevent io-error ;
31 M: kqueue-mx add-input-callback ( thread fd mx -- )
32 [ call-next-method ] [
33 [ EVFILT_READ { EV_ADD EV_ONESHOT } flags make-kevent ] dip
37 M: kqueue-mx add-output-callback ( thread fd mx -- )
38 [ call-next-method ] [
39 [ EVFILT_WRITE { EV_ADD EV_ONESHOT } flags make-kevent ] dip
43 M: kqueue-mx remove-input-callbacks ( fd mx -- seq )
45 [ call-next-method ] [
46 [ EVFILT_READ EV_DELETE make-kevent ] dip
51 M: kqueue-mx remove-output-callbacks ( fd mx -- seq )
54 [ EVFILT_WRITE EV_DELETE make-kevent ] dip
56 ] [ call-next-method ] 2bi
59 : wait-kevent ( mx timespec -- n )
62 [ events>> dup length ] bi
63 ] dip kevent multiplexer-error ;
65 : handle-kevent ( mx kevent -- )
66 [ ident>> swap ] [ filter>> ] bi {
67 { EVFILT_READ [ input-available ] }
68 { EVFILT_WRITE [ output-available ] }
71 : handle-kevents ( mx n -- )
72 [ dup events>> ] dip head-slice
73 [ handle-kevent ] with each ;
75 M: kqueue-mx wait-for-events ( us mx -- )
76 swap dup [ make-timespec ] when
77 dupd wait-kevent handle-kevents ;