factor/basis/io/backend/windows/nt/nt.factor

149 lines
4.2 KiB
Factor
Raw Normal View History

USING: alien alien.c-types arrays assocs combinators continuations
destructors io io.backend io.ports io.timeouts io.backend.windows
io.files.windows io.files.windows.nt io.files io.pathnames io.buffers
io.streams.c io.streams.null libc kernel math namespaces sequences
threads windows windows.errors windows.kernel32 strings splitting
ascii system accessors locals classes.struct ;
2007-11-14 17:04:29 -05:00
QUALIFIED: windows.winsock
IN: io.backend.windows.nt
2007-09-20 18:09:08 -04:00
2008-05-18 00:50:11 -04:00
! Global variable with assoc mapping overlapped to threads
SYMBOL: pending-overlapped
2007-09-20 18:09:08 -04:00
2008-02-18 06:07:40 -05:00
TUPLE: io-callback port thread ;
2007-09-20 18:09:08 -04:00
C: <io-callback> io-callback
: (make-overlapped) ( -- overlapped-ext )
2008-05-15 01:13:08 -04:00
"OVERLAPPED" malloc-object &free ;
2007-09-20 18:09:08 -04:00
: make-overlapped ( port -- overlapped-ext )
[ (make-overlapped) ] dip
handle>> ptr>> [ over set-OVERLAPPED-offset ] when* ;
2007-09-20 18:09:08 -04:00
2008-12-13 06:06:28 -05:00
M: winnt FileArgs-overlapped ( port -- overlapped )
make-overlapped ;
2007-11-14 17:04:29 -05:00
: <completion-port> ( handle existing -- handle )
2007-09-20 18:09:08 -04:00
f 1 CreateIoCompletionPort dup win32-error=0/f ;
2007-11-14 17:04:29 -05:00
SYMBOL: master-completion-port
: <master-completion-port> ( -- handle )
INVALID_HANDLE_VALUE f <completion-port> ;
2007-09-20 18:09:08 -04:00
M: winnt add-completion ( win32-handle -- )
handle>> master-completion-port get-global <completion-port> drop ;
2007-09-20 18:09:08 -04:00
: eof? ( error -- ? )
2008-05-18 00:50:11 -04:00
[ ERROR_HANDLE_EOF = ] [ ERROR_BROKEN_PIPE = ] bi or ;
2007-09-20 18:09:08 -04:00
2008-05-15 01:13:08 -04:00
: twiddle-thumbs ( overlapped port -- bytes-transferred )
2008-05-18 00:50:11 -04:00
[
drop
[ pending-overlapped get-global set-at ] curry "I/O" suspend
{
{ [ dup integer? ] [ ] }
{ [ dup array? ] [
first dup eof?
[ drop 0 ] [ n>win32-error-string throw ] if
2008-05-18 00:50:11 -04:00
] }
} cond
] with-timeout ;
2008-05-15 01:13:08 -04:00
:: wait-for-overlapped ( us -- bytes-transferred overlapped error? )
2008-05-15 01:13:08 -04:00
master-completion-port get-global
2008-05-18 00:50:11 -04:00
0 <int> [ ! bytes
f <void*> ! key
f <void*> [ ! overlapped
2008-11-24 06:45:57 -05:00
us [ 1000 /i ] [ INFINITE ] if* ! timeout
2008-05-18 00:50:11 -04:00
GetQueuedCompletionStatus zero?
] keep *void*
] keep *int spin ;
2007-09-20 18:09:08 -04:00
2008-05-18 00:50:11 -04:00
: resume-callback ( result overlapped -- )
pending-overlapped get-global delete-at* drop resume-with ;
2007-09-20 18:09:08 -04:00
: handle-overlapped ( us -- ? )
wait-for-overlapped [
2008-05-31 01:08:02 -04:00
dup [
[ drop GetLastError 1array ] dip resume-callback t
] [ 2drop f ] if
] [ resume-callback t ] if ;
2007-09-20 18:09:08 -04:00
M: win32-handle cancel-operation
[ check-disposed ] [ handle>> CancelIo drop ] bi ;
2007-09-20 18:09:08 -04:00
M: winnt io-multiplex ( us -- )
2008-05-15 01:13:08 -04:00
handle-overlapped [ 0 io-multiplex ] when ;
2008-04-02 21:09:56 -04:00
M: winnt init-io ( -- )
<master-completion-port> master-completion-port set-global
2008-05-18 00:50:11 -04:00
H{ } clone pending-overlapped set-global
windows.winsock:init-winsock ;
2008-05-15 02:45:32 -04:00
ERROR: invalid-file-size n ;
: handle>file-size ( handle -- n )
0 <ulonglong> [ GetFileSizeEx win32-error=0/f ] keep *ulonglong ;
ERROR: seek-before-start n ;
: set-seek-ptr ( n handle -- )
[ dup 0 < [ seek-before-start ] when ] dip (>>ptr) ;
M: winnt seek-handle ( n seek-type handle -- )
swap {
{ seek-absolute [ set-seek-ptr ] }
{ seek-relative [ [ ptr>> + ] keep set-seek-ptr ] }
{ seek-end [ [ handle>> handle>file-size + ] keep set-seek-ptr ] }
2009-02-07 12:24:12 -05:00
[ bad-seek-type ]
} case ;
2008-05-18 00:50:11 -04:00
: file-error? ( n -- eof? )
zero? [
GetLastError {
{ [ dup expected-io-error? ] [ drop f ] }
{ [ dup eof? ] [ drop t ] }
2009-04-30 14:11:51 -04:00
[ n>win32-error-string throw ]
2008-05-18 00:50:11 -04:00
} cond
] [ f ] if ;
: wait-for-file ( FileArgs n port -- n )
swap file-error?
[ 2drop 0 ] [ [ lpOverlapped>> ] dip twiddle-thumbs ] if ;
2008-05-18 00:50:11 -04:00
: update-file-ptr ( n port -- )
handle>> dup ptr>> [ rot + >>ptr drop ] [ 2drop ] if* ;
2008-05-18 00:50:11 -04:00
: finish-write ( n port -- )
2008-05-15 02:45:32 -04:00
[ update-file-ptr ] [ buffer>> buffer-consume ] 2bi ;
M: winnt (wait-to-write)
2008-05-18 00:50:11 -04:00
[
[ make-FileArgs dup setup-write WriteFile ]
[ wait-for-file ]
[ finish-write ]
tri
] with-destructors ;
2008-05-15 02:45:32 -04:00
: finish-read ( n port -- )
2008-05-18 20:02:50 -04:00
[ update-file-ptr ] [ buffer>> n>buffer ] 2bi ;
2008-05-15 02:45:32 -04:00
M: winnt (wait-to-read) ( port -- )
2008-05-18 00:50:11 -04:00
[
[ make-FileArgs dup setup-read ReadFile ]
[ wait-for-file ]
[ finish-read ]
tri
] with-destructors ;
2008-10-02 04:38:36 -04:00
2009-01-29 22:03:16 -05:00
: console-app? ( -- ? ) GetConsoleWindow >boolean ;
M: winnt init-stdio
console-app?
[ init-c-stdio ]
[ null-reader null-writer null-writer set-stdio ] if ;
winnt set-io-backend