[MLton-commit] r5277

Vesa Karvonen vesak at mlton.org
Tue Feb 20 10:33:07 PST 2007


Implemented a few extensions.
----------------------------------------------------------------------

U   mltonlib/trunk/com/ssh/windows/unstable/detail/ffi/windows.h
U   mltonlib/trunk/com/ssh/windows/unstable/detail/windows.sml

----------------------------------------------------------------------

Modified: mltonlib/trunk/com/ssh/windows/unstable/detail/ffi/windows.h
===================================================================
--- mltonlib/trunk/com/ssh/windows/unstable/detail/ffi/windows.h	2007-02-20 17:31:25 UTC (rev 5276)
+++ mltonlib/trunk/com/ssh/windows/unstable/detail/ffi/windows.h	2007-02-20 18:33:06 UTC (rev 5277)
@@ -152,6 +152,8 @@
 WIN_CONST(WAIT_TIMEOUT, DWORD);
 WIN_CONST(WAIT_FAILED, DWORD);
 
+WIN_CONST(INFINITE, DWORD);
+
 WIN_FUNCTION(WaitForMultipleObjectsEx, DWORD, 5,
              (DWORD, const HANDLE *, BOOL, DWORD, BOOL));
 WIN_FUNCTION(WaitForMultipleObjects, DWORD, 4,

Modified: mltonlib/trunk/com/ssh/windows/unstable/detail/windows.sml
===================================================================
--- mltonlib/trunk/com/ssh/windows/unstable/detail/windows.sml	2007-02-20 17:31:25 UTC (rev 5276)
+++ mltonlib/trunk/com/ssh/windows/unstable/detail/windows.sml	2007-02-20 18:33:06 UTC (rev 5277)
@@ -19,12 +19,14 @@
                       args))
       val A = layout
       val str = string
+      val lst = list
       val ptr = iso word32
                     let open MLRep.Long.Unsigned
                     in (C.Cvt.ml_ulong o C.U.p2i, C.U.i2p o C.Cvt.c_ulong)
                     end
       val opt = option
       val int = int
+      val dbl = real
       val sw = word64
    end
 
@@ -58,10 +60,23 @@
    fun raiseLastError call =
        raiseError call (getLastError ())
 
+   fun raiseLastErrorOnNull call f x = let
+      val result = f x
+   in
+      if C.Ptr.isNull' result then raiseLastError call else result
+   end
+
+   fun raiseLastErrorOnFalse call f x = let
+      val result = f x
+   in
+      if 0 = result then raiseLastError call else ()
+   end
+
    fun withAlloc alloc = With.around alloc C.free'
    fun withNew size = With.around (fn () => C.new' size) C.discard'
    fun withPtr f = withNew C.S.voidptr f
    fun withDword f = withNew C.S.ulong f
+   fun withLong f = withNew C.S.slong f
    fun withZs mlStr = withAlloc (fn () => ZString.dupML' mlStr)
    fun withBuf size = withAlloc (fn () => C.alloc' C.S.uchar size)
 
@@ -332,32 +347,94 @@
         | OBJECT of 'a
         | TIMEOUT
 
-      val any = undefined
-      val all = undefined
+      local
+         fun `x = C.Get.ulong' (x ())
+      in
+         val object    = `G_win_WAIT_OBJECT_0.obj'
+         val abandoned = `G_win_WAIT_ABANDONED_0.obj'
+         val timeout   = `G_win_WAIT_TIMEOUT.obj'
+         val failed    = `G_win_WAIT_FAILED.obj'
+         val infinite  = `G_win_INFINITE.obj'
+      end
+
+      fun wait name all ws t = let
+         val n = Word.fromInt (length ws)
+         val s = C.S.voidptr
+      in
+         (withAlloc (fn () => C.alloc' s n))
+            (fn hs =>
+                (List.appi (fn (i, (w, _)) =>
+                               C.Set.voidptr' (C.Ptr.sub' s (hs, i), w)) ws
+               ; let val res =
+                         F_win_WaitForMultipleObjects.f'
+                            (n, C.Ptr.ro' hs, if all then 1 else 0,
+                             if Real.== (t, Real.posInf)
+                             then infinite
+                             else Word.fromInt (Real.round (t * 1000.0)))
+                     fun get off = #2 (List.sub (ws, Word.toIntX (n - off)))
+                 in
+                    if res = timeout then
+                       TIMEOUT
+                    else if object <= res andalso res < object+n then
+                       OBJECT (get object)
+                    else if abandoned <= res andalso res < abandoned+n then
+                       ABANDONED (get abandoned)
+                    else if res = failed then
+                       raiseLastError
+                          (fn () => F name [A (lst ptr) (map #1 ws), A dbl t])
+                    else
+                       raise Fail "Unsupported WaitForMultipleObjects\
+                                  \ functionality"
+                 end))
+      end
+
+      fun any ? = wait "Wait.any" false ?
+      fun all ? = wait "Wait.all" true ?
    end
 
    structure Semaphore = struct
       type t = C.voidptr
-      val create = undefined
-      val close = undefined
-      val release = undefined
-      val toWait = undefined
+
+      fun create {init, max, name} = let
+         fun f name' =
+             raiseLastErrorOnNull
+                (fn () => F"Semaphore.create"
+                           [A int init, A int max, A (opt str) name])
+                F_win_CreateSemaphore.f'
+                (C.Ptr.null', init, max, name')
+      in
+         case name of
+            NONE => f C.Ptr.null'
+          | SOME n => withZs n f
+      end
+
+      val close = ignore o F_win_CloseHandle.f'
+
+      fun release (s, n) =
+          withLong
+             (fn result =>
+                 (raiseLastErrorOnFalse
+                     (fn () => F"Semaphore.release"[A ptr s, A int n])
+                     F_win_ReleaseSemaphore.f' (s, n, C.Ptr.|&! result)
+                ; C.Get.slong' result))
+
+      val toWait = id
    end
 
    structure Mutex = struct
       type t = C.voidptr
       val create = undefined
-      val close = undefined
-      val toWait = undefined
+      val close = ignore o F_win_CloseHandle.f'
+      val toWait = id
    end
 
    structure Timer = struct
       type t = C.voidptr
       val create = undefined
-      val close = undefined
+      val close = ignore o F_win_CloseHandle.f'
       val set = undefined
       val cancel = undefined
-      val toWait = undefined
+      val toWait = id
    end
 
    structure FileChange = struct
@@ -375,7 +452,7 @@
       type t = C.voidptr
       val first = undefined
       val next = undefined
-      val close = undefined
-      val toWait = undefined
+      val close = ignore o F_win_FindCloseChangeNotification.f'
+      val toWait = id
    end
 end




More information about the MLton-commit mailing list