factor/extra/io/unix/backend/kqueue/kqueue.factor

107 lines
3.0 KiB
Factor
Raw Normal View History

2008-01-18 19:43:14 -05:00
! Copyright (C) 2008 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
2008-01-18 20:29:43 -05:00
USING: alien.c-types kernel io.nonblocking io.unix.backend
io.unix.sockets sequences assocs unix unix.kqueue math
namespaces classes combinators ;
2008-01-18 19:43:14 -05:00
IN: io.unix.backend.kqueue
TUPLE: unix-kqueue-io ;
! Global variables
SYMBOL: kqueue-fd
2008-01-18 20:29:43 -05:00
SYMBOL: kqueue-added
SYMBOL: kqueue-deleted
2008-01-18 19:43:14 -05:00
SYMBOL: kqueue-events
: max-events ( -- n )
#! We read up to 256 events at a time. This is an arbitrary
#! constant...
256 ; inline
M: unix-kqueue-io init-unix-io ( -- )
2008-01-18 20:29:43 -05:00
H{ } clone kqueue-added set-global
H{ } clone kqueue-deleted set-global
2008-01-18 19:43:14 -05:00
max-events "kevent" <c-array> kqueue-events set-global
2008-01-18 20:29:43 -05:00
kqueue dup io-error kqueue-fd set-global ;
M: unix-kqueue-io register-io-task ( task -- )
dup io-task-fd kqueue-added get-global key? [ drop ] [
dup io-task-fd kqueue-deleted get-global key? [
io-task-fd kqueue-deleted get-global delete-at
] [
dup io-task-fd kqueue-added get-global set-at
] if
] if ;
M: unix-kqueue-io unregister-io-task ( task -- )
dup io-task-fd kqueue-deleted get-global key? [ drop ] [
dup io-task-fd kqueue-added get-global key? [
io-task-fd kqueue-added get-global delete-at
] [
dup io-task-fd kqueue-deleted get-global set-at
] if
] if ;
2008-01-18 19:43:14 -05:00
: io-task-filter ( task -- n )
class {
2008-01-18 20:29:43 -05:00
{ read-task [ EVFILT_READ ] }
{ accept-task [ EVFILT_READ ] }
{ receive-task [ EVFILT_READ ] }
{ write-task [ EVFILT_WRITE ] }
{ connect-task [ EVFILT_WRITE ] }
{ send-task [ EVFILT_WRITE ] }
2008-01-18 19:43:14 -05:00
} case ;
: make-kevent ( task -- event )
"kevent" <c-object>
over io-task-fd over set-kevent-ident
2008-01-18 20:29:43 -05:00
swap io-task-filter over set-kevent-filter ;
2008-01-18 19:43:14 -05:00
: make-add-kevent ( task -- event )
make-kevent
EV_ADD over set-kevent-flags ;
: make-delete-kevent ( task -- event )
make-kevent
EV_DELETE over set-kevent-flags ;
2008-01-18 20:29:43 -05:00
: kqueue-additions ( -- kevents )
kqueue-added get-global
dup clear-assoc values
[ make-add-kevent ] map ;
2008-01-18 19:43:14 -05:00
2008-01-18 20:29:43 -05:00
: kqueue-deletions ( -- kevents )
kqueue-deleted get-global
dup clear-assoc values
[ make-delete-kevent ] map ;
2008-01-18 19:43:14 -05:00
: kqueue-changelist ( -- byte-array n )
2008-01-18 20:29:43 -05:00
kqueue-additions kqueue-deletions append
dup concat f like swap length ;
2008-01-18 19:43:14 -05:00
: kqueue-eventlist ( -- byte-array n )
kqueue-events get-global max-events ;
: do-kevent ( timespec -- n )
>r
kqueue-fd get-global
kqueue-changelist
kqueue-eventlist
r> kevent dup multiplexer-error ;
: kevent-task ( kevent -- task )
2008-01-18 20:29:43 -05:00
dup kevent-ident swap kevent-filter {
2008-01-18 19:43:14 -05:00
{ [ dup EVFILT_READ = ] [ read-tasks ] }
{ [ dup EVFILT_WRITE = ] [ write-tasks ] }
2008-01-18 20:29:43 -05:00
} cond nip get at ;
2008-01-18 19:43:14 -05:00
: handle-kevents ( n eventlist -- )
[ kevent-nth kevent-task handle-fd ] curry each ;
2008-01-18 20:29:43 -05:00
M: unix-kqueue-io unix-io-multiplex ( ms -- )
2008-01-18 19:43:14 -05:00
make-timespec
do-kevent
kqueue-events get-global handle-kevents ;
T{ unix-kqueue-io } unix-io-backend set-global