factor/library/io/windows/io-internals.factor

104 lines
3.0 KiB
Factor

! Copyright (C) 2006 Mackenzie Straight, Doug Coleman.
IN: win32-io-internals
USING: alien arrays errors kernel kernel-internals math namespaces threads
vectors win32-api io generic io-internals sequences ;
SYMBOL: completion-port
SYMBOL: io-queue
TUPLE: io-queue free-list callbacks ;
TUPLE: io-callback overlapped quotation stream ;
: expected-error? ( obj -- bool )
[
ERROR_IO_PENDING ERROR_HANDLE_EOF ERROR_SUCCESS WAIT_TIMEOUT
997
] member? ;
: handle-io-error ( -- )
GetLastError expected-error? [ win32-throw-error ] unless ;
: queue-error ( len/status -- len/status )
GetLastError expected-error? [ drop f ] unless ;
: add-completion ( handle -- )
completion-port get f 1 CreateIoCompletionPort drop ;
: get-access ( -- file-mode )
"file-mode" get first2
GENERIC_WRITE 0 ? >r
GENERIC_READ 0 ? r> bitor ;
: get-sharemode ( -- share-mode )
FILE_SHARE_READ FILE_SHARE_WRITE bitor ;
: get-create ( -- creation-disposition )
"file-mode" get first2 [
[ OPEN_ALWAYS ] [ CREATE_ALWAYS ] if
] [
[ OPEN_EXISTING ] [ 0 ] if
] if ;
: win32-open-file ( file r w -- handle )
[
2array "file-mode" set
get-access get-sharemode f get-create FILE_FLAG_OVERLAPPED f
CreateFile dup INVALID_HANDLE_VALUE = [ win32-throw-error ] when
dup add-completion
] with-scope ;
: <overlapped> ( -- overlapped )
"overlapped-ext" <malloc-object> ;
C: io-queue ( -- queue )
V{ } clone over set-io-queue-callbacks ;
C: io-callback ( -- callback )
io-queue get io-queue-callbacks [ push ] 2keep
length 1 - <overlapped> [ set-overlapped-ext-user-data ] keep
swap [ set-io-callback-overlapped ] keep ;
: alloc-io-callback ( quot stream -- overlapped )
io-queue get io-queue-free-list [
first2 io-queue get [ set-io-queue-free-list ] keep
io-queue-callbacks nth
] [ <io-callback> ] if*
[ set-io-callback-stream ] keep
[ set-io-callback-quotation ] keep
io-callback-overlapped ;
: get-io-callback ( index -- callback )
dup io-queue get io-queue-callbacks nth swap
io-queue get [ io-queue-free-list 2array ] keep set-io-queue-free-list
[ f swap set-io-callback-stream ] keep
io-callback-quotation ;
: (wait-for-io) ( timeout -- error overlapped len )
>r completion-port get 0 <int> 0 <int> 0 <int>
pick over r> -rot >r >r GetQueuedCompletionStatus r> r> ;
: overlapped>callback ( overlapped -- callback )
*int dup zero? [
drop f
] [
<alien> overlapped-ext-user-data get-io-callback
] if ;
IN: win32-stream
DEFER: expire
IN: win32-io-internals
: cancel-timedout ( -- )
io-queue get
io-queue-callbacks [ io-callback-stream [ expire ] when* ] each ;
: wait-for-io ( timeout -- callback len )
(wait-for-io) overlapped>callback swap *int
rot [ queue-error ] unless ;
: win32-init-stdio ( -- )
INVALID_HANDLE_VALUE f f 1 CreateIoCompletionPort
completion-port set
<io-queue> io-queue set ;