2009-05-12 04:35:48 -04:00
|
|
|
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
|
2009-08-27 21:35:37 -04:00
|
|
|
ascii system accessors locals classes.struct combinators.short-circuit ;
|
2008-12-14 21:03:00 -05:00
|
|
|
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-11-21 01:18:46 -05:00
|
|
|
|
2007-09-20 18:09:08 -04:00
|
|
|
C: <io-callback> io-callback
|
|
|
|
|
|
|
|
: (make-overlapped) ( -- overlapped-ext )
|
2009-09-05 17:20:58 -04:00
|
|
|
OVERLAPPED malloc-struct &free ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
|
|
|
: make-overlapped ( port -- overlapped-ext )
|
2008-12-02 04:10:13 -05:00
|
|
|
[ (make-overlapped) ] dip
|
2009-09-05 17:20:58 -04:00
|
|
|
handle>> ptr>> [ >>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
|
|
|
|
2008-05-15 06:20:42 -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
|
|
|
|
2007-11-21 01:18:46 -05:00
|
|
|
: eof? ( error -- ? )
|
2009-08-27 21:35:37 -04:00
|
|
|
{ [ ERROR_HANDLE_EOF = ] [ ERROR_BROKEN_PIPE = ] } 1|| ;
|
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
|
2009-09-05 17:20:58 -04:00
|
|
|
[ >c-ptr pending-overlapped get-global set-at ] curry "I/O" suspend
|
2008-05-18 00:50:11 -04:00
|
|
|
{
|
|
|
|
{ [ dup integer? ] [ ] }
|
|
|
|
{ [ dup array? ] [
|
|
|
|
first dup eof?
|
2009-04-30 14:47:49 -04:00
|
|
|
[ 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
|
|
|
|
2008-11-24 01:51:29 -05: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?
|
2009-09-05 17:20:58 -04:00
|
|
|
] keep
|
|
|
|
*void* dup [ OVERLAPPED memory>struct ] when
|
2008-05-18 00:50:11 -04:00
|
|
|
] keep *int spin ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2008-05-18 00:50:11 -04:00
|
|
|
: resume-callback ( result overlapped -- )
|
2009-09-05 17:20:58 -04:00
|
|
|
>c-ptr pending-overlapped get-global delete-at* drop resume-with ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2008-11-24 01:51:29 -05:00
|
|
|
: handle-overlapped ( us -- ? )
|
2007-11-21 01:18:46 -05:00
|
|
|
wait-for-overlapped [
|
2009-08-27 21:35:37 -04:00
|
|
|
[
|
2008-12-02 04:10:13 -05:00
|
|
|
[ drop GetLastError 1array ] dip resume-callback t
|
2009-08-27 21:35:37 -04:00
|
|
|
] [ drop f ] if*
|
2008-12-02 04:10:13 -05:00
|
|
|
] [ resume-callback t ] if ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2008-05-21 02:36:30 -04:00
|
|
|
M: win32-handle cancel-operation
|
2008-07-08 16:50:12 -04:00
|
|
|
[ check-disposed ] [ handle>> CancelIo drop ] bi ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2008-11-24 01:51:29 -05:00
|
|
|
M: winnt io-multiplex ( us -- )
|
2008-05-15 01:13:08 -04:00
|
|
|
handle-overlapped [ 0 io-multiplex ] when ;
|
2007-09-21 18:00:47 -04:00
|
|
|
|
2008-04-02 21:09:56 -04:00
|
|
|
M: winnt init-io ( -- )
|
2007-11-21 01:18:46 -05:00
|
|
|
<master-completion-port> master-completion-port set-global
|
2009-09-04 06:02:33 -04:00
|
|
|
H{ } clone pending-overlapped set-global ;
|
2008-05-15 02:45:32 -04:00
|
|
|
|
2009-02-07 12:00:16 -05:00
|
|
|
ERROR: invalid-file-size n ;
|
|
|
|
|
|
|
|
: handle>file-size ( handle -- n )
|
|
|
|
0 <ulonglong> [ GetFileSizeEx win32-error=0/f ] keep *ulonglong ;
|
|
|
|
|
2009-02-08 21:18:30 -05:00
|
|
|
ERROR: seek-before-start n ;
|
|
|
|
|
|
|
|
: set-seek-ptr ( n handle -- )
|
|
|
|
[ dup 0 < [ seek-before-start ] when ] dip (>>ptr) ;
|
|
|
|
|
2009-02-08 11:35:30 -05:00
|
|
|
M: winnt seek-handle ( n seek-type handle -- )
|
2009-02-07 12:00:16 -05:00
|
|
|
swap {
|
2009-02-08 21:18:30 -05:00
|
|
|
{ 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 ]
|
2009-02-07 12:00:16 -05:00
|
|
|
} case ;
|
2009-02-07 02:12:03 -05:00
|
|
|
|
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?
|
2008-12-02 04:10:13 -05:00
|
|
|
[ 2drop 0 ] [ [ lpOverlapped>> ] dip twiddle-thumbs ] if ;
|
2008-05-18 00:50:11 -04:00
|
|
|
|
2008-05-15 06:20:42 -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 ;
|
2009-01-29 19:33:19 -05:00
|
|
|
|
2009-05-12 04:35:48 -04:00
|
|
|
M: winnt init-stdio
|
|
|
|
console-app?
|
|
|
|
[ init-c-stdio ]
|
2009-05-12 07:25:06 -04:00
|
|
|
[ null-reader null-writer null-writer set-stdio ] if ;
|
2008-12-13 05:49:28 -05:00
|
|
|
|
|
|
|
winnt set-io-backend
|