File: world5.sml

package info (click to toggle)
mlton 20100608-2
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 34,980 kB
  • ctags: 69,089
  • sloc: ansic: 18,421; lisp: 2,879; makefile: 1,570; sh: 1,325; pascal: 256; asm: 97
file content (61 lines) | stat: -rw-r--r-- 1,697 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
fun run (f: unit -> unit) =
   case Posix.Process.fork () of
      SOME pid =>
         let
            open Posix.Process
            val (pid', status) = waitpid (W_CHILD pid, [])
         in if pid = pid' andalso status = W_EXITED
               then ()
            else raise Fail "child failed"
         end
    | NONE => let open OS.Process
              in exit ((f (); success) handle _ => failure)
              end

fun succeed () =
   let open OS.Process
   in exit success
   end

open MLton.World MLton.Signal Posix.Signal Posix.Process Posix.ProcEnv

val (w, out) = MLton.TextIO.mkstemp "/tmp/world"
val _ = TextIO.closeOut out

val childReady = ref false

fun print s = TextIO.output (TextIO.stdErr, s)

val _ = setHandler (usr1, Handler.simple (fn () => childReady := true))
   
val parent = getpid ()

val _ =
   case fork () of
      NONE =>
         let
            val canExit = ref false
         in
            setHandler (usr1, Handler.handler (fn t => (canExit := true
                                                        ; saveThread (w, t)
                                                        ; t)))
            ; kill (K_PROC parent, usr1)
            ; let
                 fun loop () = if !canExit then print "success\n" else loop ()
              in
                 loop ()
              end
            ; let open OS.Process
              in exit success
              end
         end
    | SOME child =>
         let
            fun loop () = if !childReady then () else loop ()
         in
            loop ()
            ; kill (K_PROC child, usr1)
            ; wait ()
            ; run (fn () => load w)
            ; OS.FileSys.remove w
         end