2007-11-07 14:01:45 -05:00
|
|
|
USING: alien alien.c-types arrays assocs combinators
|
|
|
|
continuations destructors io io.backend io.nonblocking
|
|
|
|
io.windows libc kernel math namespaces sequences threads
|
|
|
|
tuples.lib windows windows.errors windows.kernel32 strings
|
2007-11-14 17:04:29 -05:00
|
|
|
splitting io.files qualified ;
|
|
|
|
QUALIFIED: windows.winsock
|
2007-09-20 18:09:08 -04:00
|
|
|
IN: io.windows.nt.backend
|
|
|
|
|
2007-09-21 18:00:47 -04:00
|
|
|
: unicode-prefix ( -- seq )
|
|
|
|
"\\\\?\\" ; inline
|
|
|
|
|
2007-11-12 01:41:13 -05:00
|
|
|
M: windows-nt-io root-directory? ( path -- ? )
|
|
|
|
dup length 2 = [
|
|
|
|
dup first Letter?
|
|
|
|
swap second CHAR: : = and
|
|
|
|
] [
|
|
|
|
drop f
|
|
|
|
] if ;
|
|
|
|
|
2007-09-21 18:00:47 -04:00
|
|
|
M: windows-nt-io normalize-pathname ( string -- string )
|
|
|
|
dup string? [ "pathname must be a string" throw ] unless
|
|
|
|
"/" split "\\" join
|
|
|
|
{
|
|
|
|
! empty
|
|
|
|
{ [ dup empty? ] [ "empty path" throw ] }
|
|
|
|
! .\\foo
|
|
|
|
{ [ dup ".\\" head? ] [
|
|
|
|
>r unicode-prefix cwd r> 1 tail 3append
|
|
|
|
] }
|
2007-12-06 03:21:54 -05:00
|
|
|
! c:\\foo
|
2007-09-21 18:00:47 -04:00
|
|
|
{ [ dup 1 tail ":" head? ] [ >r unicode-prefix r> append ] }
|
|
|
|
! \\\\?\\c:\\foo
|
|
|
|
{ [ dup unicode-prefix head? ] [ ] }
|
|
|
|
! foo.txt ..\\foo.txt
|
|
|
|
{ [ t ] [
|
|
|
|
[
|
|
|
|
unicode-prefix % cwd %
|
|
|
|
dup first CHAR: \\ = [ CHAR: \\ , ] unless %
|
|
|
|
] "" make
|
|
|
|
] }
|
2007-12-06 03:21:54 -05:00
|
|
|
} cond [ "/\\." member? ] right-trim
|
|
|
|
dup peek CHAR: : = [ "\\" append ] when ;
|
2007-09-21 18:00:47 -04:00
|
|
|
|
2007-09-20 18:09:08 -04:00
|
|
|
SYMBOL: io-hash
|
|
|
|
|
2007-11-21 01:18:46 -05:00
|
|
|
TUPLE: io-callback continuation port ;
|
|
|
|
|
2007-09-20 18:09:08 -04:00
|
|
|
C: <io-callback> io-callback
|
|
|
|
|
|
|
|
: (make-overlapped) ( -- overlapped-ext )
|
2007-10-15 16:01:55 -04:00
|
|
|
"OVERLAPPED" malloc-object dup free-always
|
2007-09-20 18:09:08 -04:00
|
|
|
0 over set-OVERLAPPED-internal
|
|
|
|
0 over set-OVERLAPPED-internal-high
|
|
|
|
0 over set-OVERLAPPED-offset-high
|
|
|
|
0 over set-OVERLAPPED-offset
|
|
|
|
f over set-OVERLAPPED-event ;
|
|
|
|
|
|
|
|
: make-overlapped ( port -- overlapped-ext )
|
|
|
|
>r (make-overlapped) r> port-handle win32-file-ptr
|
|
|
|
[ over set-OVERLAPPED-offset ] when* ;
|
|
|
|
|
2007-11-07 14:01:45 -05:00
|
|
|
: port-overlapped ( port -- overlapped )
|
|
|
|
port-handle win32-file-overlapped ;
|
|
|
|
|
|
|
|
: set-port-overlapped ( overlapped port -- )
|
|
|
|
port-handle set-win32-file-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: windows-nt-io add-completion ( handle -- )
|
2007-11-14 17:04:29 -05:00
|
|
|
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 -- ? )
|
|
|
|
dup ERROR_HANDLE_EOF = swap ERROR_BROKEN_PIPE = or ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2007-11-21 01:18:46 -05:00
|
|
|
: overlapped-error? ( port n -- ? )
|
|
|
|
zero? [
|
|
|
|
GetLastError {
|
|
|
|
{ [ dup expected-io-error? ] [ 2drop t ] }
|
|
|
|
{ [ dup eof? ] [ drop t swap set-port-eof? f ] }
|
|
|
|
{ [ t ] [ (win32-error-string) throw ] }
|
|
|
|
} cond
|
|
|
|
] [
|
|
|
|
drop t
|
|
|
|
] if ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2007-11-21 01:18:46 -05:00
|
|
|
: get-overlapped-result ( port -- bytes-transferred )
|
|
|
|
dup
|
|
|
|
port-handle
|
|
|
|
dup win32-file-handle
|
|
|
|
swap win32-file-overlapped
|
|
|
|
0 <uint> [
|
|
|
|
0
|
|
|
|
GetOverlappedResult overlapped-error? drop
|
|
|
|
] keep *uint ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
|
|
|
: save-callback ( port -- )
|
|
|
|
[
|
2007-11-21 01:18:46 -05:00
|
|
|
[ <io-callback> ] keep port-handle win32-file-overlapped
|
|
|
|
io-hash get-global set-at stop
|
|
|
|
] curry callcc0 ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2007-11-21 01:18:46 -05:00
|
|
|
: wait-for-overlapped ( ms -- overlapped ? )
|
|
|
|
>r master-completion-port get-global r> ! port ms
|
|
|
|
0 <int> ! bytes
|
|
|
|
f <void*> ! key
|
|
|
|
f <void*> ! overlapped
|
|
|
|
[ roll GetQueuedCompletionStatus ] keep *void* swap zero? ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2007-09-21 18:00:47 -04:00
|
|
|
: lookup-callback ( GetQueuedCompletion-args -- callback )
|
2007-11-07 14:01:45 -05:00
|
|
|
io-hash get-global delete-at* drop ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
|
|
|
: wait-for-io ( timeout -- continuation/f )
|
2007-11-21 01:18:46 -05:00
|
|
|
wait-for-overlapped [
|
|
|
|
GetLastError dup expected-io-error? [
|
2007-09-20 18:09:08 -04:00
|
|
|
2drop f
|
|
|
|
] [
|
2007-11-21 01:18:46 -05:00
|
|
|
dup eof? [
|
|
|
|
drop lookup-callback
|
|
|
|
dup io-callback-port t swap set-port-eof?
|
|
|
|
io-callback-continuation
|
2007-09-21 18:00:47 -04:00
|
|
|
] [
|
|
|
|
(win32-error-string) swap lookup-callback
|
2007-09-20 18:09:08 -04:00
|
|
|
[ io-callback-port set-port-error ] keep
|
|
|
|
io-callback-continuation
|
|
|
|
] if
|
|
|
|
] if
|
|
|
|
] [
|
2007-09-21 18:00:47 -04:00
|
|
|
lookup-callback io-callback-continuation
|
2007-09-20 18:09:08 -04:00
|
|
|
] if ;
|
|
|
|
|
|
|
|
: maybe-expire ( io-callbck -- )
|
|
|
|
io-callback-port
|
|
|
|
dup timeout? [
|
|
|
|
port-handle win32-file-handle CancelIo drop
|
|
|
|
] [
|
|
|
|
drop
|
|
|
|
] if ;
|
|
|
|
|
2007-11-07 14:01:45 -05:00
|
|
|
: cancel-timeout ( -- )
|
2007-09-20 18:09:08 -04:00
|
|
|
io-hash get-global values [ maybe-expire ] each ;
|
|
|
|
|
|
|
|
M: windows-nt-io io-multiplex ( ms -- )
|
2007-11-07 14:01:45 -05:00
|
|
|
cancel-timeout wait-for-io [ schedule-thread ] when* ;
|
2007-09-21 18:00:47 -04:00
|
|
|
|
|
|
|
M: windows-nt-io init-io ( -- )
|
2007-11-21 01:18:46 -05:00
|
|
|
<master-completion-port> master-completion-port set-global
|
|
|
|
H{ } clone io-hash set-global
|
|
|
|
windows.winsock:init-winsock ;
|