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
5 specialized-arrays unix unix.kqueue unix.time assocs
6 io.backend.unix.multiplexers classes.struct ;
7 SPECIALIZED-ARRAY: kevent
8 IN: io.backend.unix.multiplexers.kqueue
10 TUPLE: kqueue-mx < mx events ;
12 ! We read up to 256 events at a time. This is an arbitrary
14 CONSTANT: max-events 256
16 : <kqueue-mx> ( -- mx )
18 kqueue dup io-error >>fd
19 max-events <kevent-array> >>events ;
21 M: kqueue-mx dispose* fd>> close-file ;
23 : make-kevent ( fd filter flags -- event )
29 : register-kevent ( kevent mx -- )
30 fd>> swap 1 f 0 f kevent io-error ;
32 M: kqueue-mx add-input-callback ( thread fd mx -- )
33 [ call-next-method ] [
34 [ EVFILT_READ { EV_ADD EV_ONESHOT } flags make-kevent ] dip
38 M: kqueue-mx add-output-callback ( thread fd mx -- )
39 [ call-next-method ] [
40 [ EVFILT_WRITE { EV_ADD EV_ONESHOT } flags make-kevent ] dip
44 M: kqueue-mx remove-input-callbacks ( fd mx -- seq )
46 [ call-next-method ] [
47 [ EVFILT_READ EV_DELETE make-kevent ] dip
52 M: kqueue-mx remove-output-callbacks ( fd mx -- seq )
55 [ EVFILT_WRITE EV_DELETE make-kevent ] dip
57 ] [ call-next-method ] 2bi
60 : wait-kevent ( mx timespec -- n )
63 [ events>> dup length ] bi
64 ] dip kevent multiplexer-error ;
66 : handle-kevent ( mx kevent -- )
67 [ ident>> swap ] [ filter>> ] bi {
68 { EVFILT_READ [ input-available ] }
69 { EVFILT_WRITE [ output-available ] }
72 : handle-kevents ( mx n -- )
73 [ dup events>> ] dip head-slice
74 [ handle-kevent ] with each ;
76 M: kqueue-mx wait-for-events ( nanos mx -- )
77 swap dup [ make-timespec ] when
78 dupd wait-kevent handle-kevents ;