Mac OS X monitors work in progress
parent
ffcc11559f
commit
e64089fd0a
|
@ -1,35 +1,45 @@
|
|||
! Copyright (C) 2006 Slava Pestov
|
||||
! Copyright (C) 2006, 2008 Slava Pestov
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: alien alien.c-types alien.syntax kernel math sequences ;
|
||||
IN: core-foundation
|
||||
|
||||
TYPEDEF: void* CFAllocatorRef
|
||||
TYPEDEF: void* CFArrayRef
|
||||
TYPEDEF: void* CFBundleRef
|
||||
TYPEDEF: void* CFStringRef
|
||||
TYPEDEF: void* CFURLRef
|
||||
TYPEDEF: void* CFUUIDRef
|
||||
TYPEDEF: void* CFRunLoopRef
|
||||
TYPEDEF: bool Boolean
|
||||
TYPEDEF: int CFIndex
|
||||
TYPEDEF: double CFTimeInterval
|
||||
TYPEDEF: double CFAbsoluteTime
|
||||
|
||||
FUNCTION: void* CFArrayCreateMutable ( void* allocator, CFIndex capacity, void* callbacks ) ;
|
||||
FUNCTION: CFArrayRef CFArrayCreateMutable ( CFAllocatorRef allocator, CFIndex capacity, void* callbacks ) ;
|
||||
|
||||
FUNCTION: void* CFArrayGetValueAtIndex ( void* array, CFIndex idx ) ;
|
||||
FUNCTION: void* CFArrayGetValueAtIndex ( CFArrayRef array, CFIndex idx ) ;
|
||||
|
||||
FUNCTION: void CFArraySetValueAtIndex ( void* array, CFIndex index, void* value ) ;
|
||||
FUNCTION: void CFArraySetValueAtIndex ( CFArrayRef array, CFIndex index, void* value ) ;
|
||||
|
||||
FUNCTION: CFIndex CFArrayGetCount ( void* array ) ;
|
||||
FUNCTION: CFIndex CFArrayGetCount ( CFArrayRef array ) ;
|
||||
|
||||
: kCFURLPOSIXPathStyle 0 ;
|
||||
|
||||
FUNCTION: void* CFURLCreateWithFileSystemPath ( void* allocator, void* filePath, int pathStyle, bool isDirectory ) ;
|
||||
FUNCTION: CFURLRef CFURLCreateWithFileSystemPath ( CFAllocatorRef allocator, CFStringRef filePath, int pathStyle, Boolean isDirectory ) ;
|
||||
|
||||
FUNCTION: void* CFURLCreateWithString ( void* allocator, void* string, void* base ) ;
|
||||
FUNCTION: CFURLRef CFURLCreateWithString ( CFAllocatorRef allocator, CFStringRef string, CFURLRef base ) ;
|
||||
|
||||
FUNCTION: void* CFURLCopyFileSystemPath ( void* url, int pathStyle ) ;
|
||||
FUNCTION: CFURLRef CFURLCopyFileSystemPath ( CFURLRef url, int pathStyle ) ;
|
||||
|
||||
FUNCTION: void* CFStringCreateWithCharacters ( void* allocator, ushort* cStr, CFIndex numChars ) ;
|
||||
FUNCTION: CFStringRef CFStringCreateWithCharacters ( CFAllocatorRef allocator, ushort* cStr, CFIndex numChars ) ;
|
||||
|
||||
FUNCTION: CFIndex CFStringGetLength ( void* theString ) ;
|
||||
FUNCTION: CFIndex CFStringGetLength ( CFStringRef theString ) ;
|
||||
|
||||
FUNCTION: void CFStringGetCharacters ( void* theString, CFIndex start, CFIndex length, void* buffer ) ;
|
||||
|
||||
FUNCTION: void* CFBundleCreate ( void* allocator, void* bundleURL ) ;
|
||||
FUNCTION: CFBundleRef CFBundleCreate ( CFAllocatorRef allocator, CFURLRef bundleURL ) ;
|
||||
|
||||
FUNCTION: bool CFBundleLoadExecutable ( void* bundle ) ;
|
||||
FUNCTION: Boolean CFBundleLoadExecutable ( CFBundleRef bundle ) ;
|
||||
|
||||
FUNCTION: void CFRelease ( void* cf ) ;
|
||||
|
||||
|
@ -52,6 +62,9 @@ FUNCTION: void CFRelease ( void* cf ) ;
|
|||
: CF>string-array ( alien -- seq )
|
||||
CF>array [ CF>string ] map ;
|
||||
|
||||
: <CFStringArray> ( seq -- alien )
|
||||
[ <CFString> ] map dup <CFArray> swap [ CFRelease ] each ;
|
||||
|
||||
: <CFFileSystemURL> ( string dir? -- url )
|
||||
>r <CFString> f over kCFURLPOSIXPathStyle
|
||||
r> CFURLCreateWithFileSystemPath swap CFRelease ;
|
||||
|
@ -72,3 +85,5 @@ FUNCTION: void CFRelease ( void* cf ) ;
|
|||
] [
|
||||
"Cannot load bundled named " swap append throw
|
||||
] ?if ;
|
||||
|
||||
FUNCTION: CFRunLoopRef CFRunLoopGetMain ( ) ;
|
||||
|
|
|
@ -0,0 +1,203 @@
|
|||
! Copyright (C) 2008 Slava Pestov
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: alien alien.c-types alien.syntax kernel math sequences
|
||||
namespaces assocs init continuations ;
|
||||
IN: core-foundation
|
||||
|
||||
! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
|
||||
! FSEventStream API, Leopard only !
|
||||
! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! !
|
||||
|
||||
: kFSEventStreamCreateFlagUseCFTypes 2 ; inline
|
||||
: kFSEventStreamCreateFlagWatchRoot 4 ; inline
|
||||
|
||||
: kFSEventStreamEventFlagMustScanSubDirs 1 ; inline
|
||||
: kFSEventStreamEventFlagUserDropped 2 ; inline
|
||||
: kFSEventStreamEventFlagKernelDropped 4 ; inline
|
||||
: kFSEventStreamEventFlagEventIdsWrapped 8 ; inline
|
||||
: kFSEventStreamEventFlagHistoryDone 16 ; inline
|
||||
: kFSEventStreamEventFlagRootChanged 32 ; inline
|
||||
: kFSEventStreamEventFlagMount 64 ; inline
|
||||
: kFSEventStreamEventFlagUnmount 128 ; inline
|
||||
|
||||
TYPEDEF: int FSEventStreamCreateFlags
|
||||
TYPEDEF: int FSEventStreamEventFlags
|
||||
TYPEDEF: longlong FSEventStreamEventId
|
||||
TYPEDEF: void* FSEventStreamRef
|
||||
|
||||
C-STRUCT: FSEventStreamContext
|
||||
{ "CFIndex" "version" }
|
||||
{ "void*" "info" }
|
||||
{ "void*" "retain" }
|
||||
{ "void*" "release" }
|
||||
{ "void*" "copyDescription" } ;
|
||||
|
||||
! callback(FSEventStreamRef streamRef, void *clientCallBackInfo, size_t numEvents, void *eventPaths, const FSEventStreamEventFlags eventFlags[], const FSEventStreamEventId eventIds[]);
|
||||
TYPEDEF: void* FSEventStreamCallback
|
||||
|
||||
: FSEventStreamEventIdSinceNow HEX: FFFFFFFFFFFFFFFF ; inline
|
||||
|
||||
FUNCTION: FSEventStreamRef FSEventStreamCreate (
|
||||
CFAllocatorRef allocator,
|
||||
FSEventStreamCallback callback,
|
||||
FSEventStreamContext* context,
|
||||
CFArrayRef pathsToWatch,
|
||||
FSEventStreamEventId sinceWhen,
|
||||
CFTimeInterval latency,
|
||||
FSEventStreamCreateFlags flags ) ;
|
||||
|
||||
FUNCTION: FSEventStreamRef FSEventStreamCreateRelativeToDevice (
|
||||
CFAllocatorRef allocator,
|
||||
FSEventStreamCallback callback,
|
||||
FSEventStreamContext* context,
|
||||
dev_t deviceToWatch,
|
||||
CFArrayRef pathsToWatchRelativeToDevice,
|
||||
FSEventStreamEventId sinceWhen,
|
||||
CFTimeInterval latency,
|
||||
FSEventStreamCreateFlags flags ) ;
|
||||
|
||||
FUNCTION: FSEventStreamEventId FSEventStreamGetLatestEventId ( FSEventStreamRef streamRef ) ;
|
||||
|
||||
FUNCTION: dev_t FSEventStreamGetDeviceBeingWatched ( FSEventStreamRef streamRef ) ;
|
||||
|
||||
FUNCTION: CFArrayRef FSEventStreamCopyPathsBeingWatched ( FSEventStreamRef streamRef ) ;
|
||||
|
||||
FUNCTION: FSEventStreamEventId FSEventsGetCurrentEventId ( ) ;
|
||||
|
||||
FUNCTION: CFUUIDRef FSEventsCopyUUIDForDevice ( dev_t dev ) ;
|
||||
|
||||
FUNCTION: FSEventStreamEventId FSEventsGetLastEventIdForDeviceBeforeTime (
|
||||
dev_t dev,
|
||||
CFAbsoluteTime time ) ;
|
||||
|
||||
FUNCTION: Boolean FSEventsPurgeEventsForDeviceUpToEventId (
|
||||
dev_t dev,
|
||||
FSEventStreamEventId eventId ) ;
|
||||
|
||||
FUNCTION: void FSEventStreamRetain ( FSEventStreamRef streamRef ) ;
|
||||
|
||||
FUNCTION: void FSEventStreamRelease ( FSEventStreamRef streamRef ) ;
|
||||
|
||||
FUNCTION: void FSEventStreamScheduleWithRunLoop (
|
||||
FSEventStreamRef streamRef,
|
||||
CFRunLoopRef runLoop,
|
||||
CFStringRef runLoopMode ) ;
|
||||
|
||||
FUNCTION: void FSEventStreamUnscheduleFromRunLoop (
|
||||
FSEventStreamRef streamRef,
|
||||
CFRunLoopRef runLoop,
|
||||
CFStringRef runLoopMode ) ;
|
||||
|
||||
FUNCTION: void FSEventStreamInvalidate ( FSEventStreamRef streamRef ) ;
|
||||
|
||||
FUNCTION: Boolean FSEventStreamStart ( FSEventStreamRef streamRef ) ;
|
||||
|
||||
FUNCTION: FSEventStreamEventId FSEventStreamFlushAsync ( FSEventStreamRef streamRef ) ;
|
||||
|
||||
FUNCTION: void FSEventStreamFlushSync ( FSEventStreamRef streamRef ) ;
|
||||
|
||||
FUNCTION: void FSEventStreamStop ( FSEventStreamRef streamRef ) ;
|
||||
|
||||
FUNCTION: void FSEventStreamShow ( FSEventStreamRef streamRef ) ;
|
||||
|
||||
FUNCTION: CFStringRef FSEventStreamCopyDescription ( FSEventStreamRef streamRef ) ;
|
||||
|
||||
: make-FSEventStreamContext ( info -- alien )
|
||||
"FSEventStreamContext" <c-object>
|
||||
[ set-FSEventStreamContext-info ] keep ;
|
||||
|
||||
: <FSEventStream> ( callback info paths latency flags -- event-stream )
|
||||
>r >r >r >r >r
|
||||
f ! allocator
|
||||
r> ! callback
|
||||
r> make-FSEventStreamContext
|
||||
r> <CFStringArray> ! paths
|
||||
FSEventStreamEventIdSinceNow ! sinceWhen
|
||||
r> ! latency
|
||||
r> ! flags
|
||||
FSEventStreamCreate ;
|
||||
|
||||
: kCFRunLoopCommonModes ( -- string )
|
||||
"kCFRunLoopCommonModes" f dlsym *void* ;
|
||||
|
||||
: schedule-event-stream ( event-stream -- )
|
||||
CFRunLoopGetMain
|
||||
kCFRunLoopCommonModes
|
||||
FSEventStreamScheduleWithRunLoop ;
|
||||
|
||||
: unschedule-event-stream ( event-stream -- )
|
||||
CFRunLoopGetMain
|
||||
kCFRunLoopCommonModes
|
||||
FSEventStreamUnscheduleFromRunLoop ;
|
||||
|
||||
: enable-event-stream ( event-stream -- )
|
||||
dup
|
||||
schedule-event-stream
|
||||
dup FSEventStreamStart [
|
||||
drop
|
||||
] [
|
||||
dup unschedule-event-stream
|
||||
FSEventStreamRelease
|
||||
"Cannot enable FSEventStream" throw
|
||||
] if ;
|
||||
|
||||
: disable-event-stream ( event-stream -- )
|
||||
dup FSEventStreamStop
|
||||
unschedule-event-stream ;
|
||||
|
||||
SYMBOL: event-stream-callbacks
|
||||
|
||||
: event-stream-counter \ event-stream-counter counter ;
|
||||
|
||||
[
|
||||
H{ } clone event-stream-callbacks set-global
|
||||
1 \ event-stream-counter set-global
|
||||
] "core-foundation" add-init-hook
|
||||
|
||||
event-stream-callbacks global [ H{ } assoc-like ] change-at
|
||||
|
||||
: add-event-source-callback ( quot -- id )
|
||||
event-stream-counter <alien>
|
||||
[ event-stream-callbacks get set-at ] keep ;
|
||||
|
||||
: remove-event-source-callback ( id -- )
|
||||
event-stream-callbacks get delete-at ;
|
||||
|
||||
: >event-triple ( n eventPaths eventFlags eventIds -- triple )
|
||||
[
|
||||
>r >r >r dup dup
|
||||
r> char*-nth ,
|
||||
r> int-nth ,
|
||||
r> longlong-nth ,
|
||||
] { } make ;
|
||||
|
||||
: master-event-source-callback ( -- alien )
|
||||
"void"
|
||||
{
|
||||
"FSEventStreamRef"
|
||||
"void*" ! info
|
||||
"size_t" ! numEvents
|
||||
"void*" ! eventPaths
|
||||
"FSEventStreamEventFlags*"
|
||||
"FSEventStreamEventId*"
|
||||
}
|
||||
"cdecl" [
|
||||
[ >event-triple ] 3curry map
|
||||
swap event-stream-callbacks get at call
|
||||
drop
|
||||
] alien-callback ;
|
||||
|
||||
TUPLE: event-stream info handle ;
|
||||
|
||||
: <event-stream> ( quot paths latency flags -- event-stream )
|
||||
>r >r >r
|
||||
add-event-source-callback dup
|
||||
>r master-event-source-callback r>
|
||||
r> r> r> <FSEventStream>
|
||||
dup enable-event-stream
|
||||
event-stream construct-boa ;
|
||||
|
||||
M: event-stream dispose
|
||||
dup event-stream-info remove-event-source-callback
|
||||
event-stream-handle dup disable-event-stream
|
||||
FSEventStreamRelease ;
|
|
@ -5,14 +5,14 @@ USING: io.backend io.unix.backend io.unix.kqueue io.unix.select
|
|||
io.launcher io.unix.launcher namespaces kernel assocs threads
|
||||
continuations ;
|
||||
|
||||
! On *BSD and Mac OS X, we use select() for the top-level
|
||||
! multiplexer, and we hang a kqueue off of it but file change
|
||||
! notification and process exit notification.
|
||||
! On Mac OS X, we use select() for the top-level
|
||||
! multiplexer, and we hang a kqueue off of it for process exit
|
||||
! notification.
|
||||
|
||||
! kqueue is buggy with files and ptys so we can't use it as the
|
||||
! main multiplexer.
|
||||
|
||||
TUPLE: bsd-io ;
|
||||
MIXIN: bsd-io
|
||||
|
||||
INSTANCE: bsd-io unix-io
|
||||
|
||||
|
@ -25,5 +25,3 @@ M: bsd-io init-io ( -- )
|
|||
|
||||
M: bsd-io register-process ( process -- )
|
||||
process-handle kqueue-mx get-global add-pid-task ;
|
||||
|
||||
T{ bsd-io } set-io-backend
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
IN: io.unix.freebsd
|
||||
USING: io.unix.bsd io.backend core-foundation.fsevents ;
|
||||
|
||||
TUPLE: freebsd-io ;
|
||||
|
||||
INSTANCE: freebsd-io bsd-io
|
||||
|
||||
T{ freebsd-io } set-io-backend
|
|
@ -136,5 +136,3 @@ M: linux-io init-io ( -- )
|
|||
T{ linux-io } set-io-backend
|
||||
|
||||
[ start-wait-thread ] "io.unix.linux" add-init-hook
|
||||
|
||||
"vocabs.monitor" require
|
|
@ -0,0 +1,27 @@
|
|||
IN: io.unix.macosx
|
||||
USING: io.unix.bsd io.backend io.monitors io.monitors.private
|
||||
continuations kernel core-foundation.fsevents ;
|
||||
|
||||
TUPLE: macosx-io ;
|
||||
|
||||
INSTANCE: macosx-io bsd-io
|
||||
|
||||
T{ macosx-io } set-io-backend
|
||||
|
||||
TUPLE: macosx-monitor ;
|
||||
|
||||
: enqueue-notifications ( triples monitor -- )
|
||||
monitor-queue [
|
||||
[ first { +modify-file+ } swap changed-file ] each
|
||||
] bind ;
|
||||
|
||||
M: macosx-io <monitor>
|
||||
drop
|
||||
f macosx-monitor construct-simple-monitor
|
||||
dup [ enqueue-notifications ] curry
|
||||
rot 1array 0 0 <event-stream>
|
||||
over set-simple-monitor-handle ;
|
||||
|
||||
M: macosx-monitor dispose
|
||||
dup simple-monitor-handle dispose delegate dispose ;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
IN: io.unix.netbsd
|
||||
USING: io.unix.bsd io.backend ;
|
||||
|
||||
TUPLE: netbsd-io ;
|
||||
|
||||
INSTANCE: netbsd-io bsd-io
|
||||
|
||||
T{ netbsd-io } set-io-backend
|
|
@ -0,0 +1,8 @@
|
|||
IN: io.unix.openbsd
|
||||
USING: io.unix.bsd io.backend core-foundation.fsevents ;
|
||||
|
||||
TUPLE: openbsd-io ;
|
||||
|
||||
INSTANCE: openbsd-io bsd-io
|
||||
|
||||
T{ openbsd-io } set-io-backend
|
|
@ -2,9 +2,6 @@ USING: io.unix.backend io.unix.files io.unix.sockets io.timeouts
|
|||
io.unix.launcher io.unix.mmap io.backend combinators namespaces
|
||||
system vocabs.loader ;
|
||||
|
||||
{
|
||||
{ [ bsd? ] [ "io.unix.bsd" ] }
|
||||
{ [ macosx? ] [ "io.unix.bsd" ] }
|
||||
{ [ linux? ] [ "io.unix.linux" ] }
|
||||
{ [ solaris? ] [ "io.unix.solaris" ] }
|
||||
} cond require
|
||||
"io.unix." os append require
|
||||
|
||||
"vocabs.monitor" require
|
||||
|
|
|
@ -12,5 +12,3 @@ USE: io.windows.mmap
|
|||
USE: io.backend
|
||||
|
||||
T{ windows-nt-io } set-io-backend
|
||||
|
||||
"vocabs.monitor" require
|
||||
|
|
Loading…
Reference in New Issue