[MLton] Re: exene example
Lukasz S Ziarek
lziarek@cs.purdue.edu
Wed, 31 Aug 2005 16:22:36 -0500
Stephen Weeks wrote:
>Luke sent a large (>5M) email to Matthew, and it looks like Matthew
>resent it to the MLton list, at which point mailman complained because
>the message was too large. Matthew approved it, and that hung mailman
>on mlton.org because python is slow as a dog. I killed it, since I
>don't really want such a huge message to go out to the list 60 people.
>
>The discussion certainly belongs on the list, but huge examples like
>that should be placed at URLs or sent via email off list. So, Luke,
>could you please resend your mail to the whole list sans huge example,
>and place the example at a URL (preferred) or email it just to
>Matthew. Thanks.
>
>
(here is a resend of the email, with some more examples added)
Mathew,
Here is the non working copy of eXene and a MLton with all apropriate
changes to the basis and CML needed to build exene. The main change to
MLton was adding a packword16 functor (also the reason why i cannot
compile with keep exception history true), its located where packword32
is. There are a few additions to CML which I will explain shortly. To
build a runable with exene, simply go to
portExene/eXene/examples/triangle and build the sources.mlb there. To
edit the triangles example edit mltontri.sml. This verion of exene
dumps a lot of output to the screen, what you are looking for is:
exenedebugphil: xio ending bc of SysErr txt=(Interrupted system call)
msg=(Interrupted system call) name=intr) thrown in xio
which is handled in eXene/lib/protocol/xio.sml
----
fun loop () = (
CML.send (outCh, getMsg());
loop ())
in
loop () handle LostReply => (print "exenedebugphil: xio
ending bc of LostReply thrown in xio\n"; CML.exit())
| Fail(cause) => (print ("exenedebugphil: xio
ending bc of Fail (" ^ cause ^ ") thrown in xio\n"); CML.exit())
| OS.SysErr (cause, SOME (err)) =>(print
("exenedebugphil: xio ending bc of SysErr txt=("
^ cause
^ ")
msg=("
^
OS.errorMsg err
^ ")
name="
^
OS.errorName err
^ ")
thrown in xio\n"); raise OS.SysErr (cause, SOME (err)))
(*| _ => (print "exenedebugphil: xio ending bc
of some other exn thrown in xio\n"; CML.exit())*)
end
-----
This is the code that causes the system call interrupted error, also in
xio.sml
----
fun readVec (n, hdr) = let
val _ = print "exenedebugphil:xio.readVec start\n"
val _ = MLton.Thread.atomicBegin()
fun read (0, [v]) = v
| read (0, vl) = W8V.concat(List.rev vl)
| read (n, vl) = let
val v = let val _ = print "exenedebugphil:xio.readVec
before socket\n"
val _ = print
("exenedebugphil:xio.readVec n=" ^ Int.toString n ^ "\n")
val ret = check(fn =>
Socket.recvVec(sock, n))
val _ = print
"exenedebugphil:xio.readVec after socket\n"
in ret
end
in
case (W8V.length v)
of 0 => raise Fail "Socket closed"
| len => read (n - len, v::vl)
(* end case *)
end
val ret = read (n, hdr)
val _ = MLton.Thread.atomicEnd()
in ret
end
-----
If you remove the atomics, the error should go away, though exene will
not work. In the above example code, the check function is our spin
lock, allowing only one Socket call at a time.
Type inference issues....
For whatever reason we had many problems with infering option types in
this exene build. Please take a look at the following example also in
xio.sml
---
fun gobbleAndFlush arg = let
fun loop arg =
let val _ = MLton.Thread.atomicBegin()
in
if CML.isEmpty (reqCh)
then (MLton.Thread.atomicEnd(); arg)
else let val req = (CML.recv reqCh)
val _ = MLton.Thread.atomicEnd()
in case req
of RequestFlush => loop arg
| RequestQuit => quit()
| (Request req) => loop (doRequest(req, arg))
| (RequestAndChk req) => loop (doRequestAndChk
(req, arg))
| (RequestReply req) => loop (doRequestReply
(req, arg))
| (RequestReplies req) =>
loop (doRequestReplies (req, arg))
| (RequestExposures req) =>
loop (doRequestExposures (req, arg))
end
end
(*
fun loop arg = (case (CML.recvPoll (reqCh))
of NONE => arg
| (SOME RequestFlush) => loop arg
| (SOME RequestQuit) => quit()
| (SOME(Request req)) => loop (doRequest(req, arg))
| (SOME(RequestAndChk req)) => loop (doRequestAndChk (req, arg))
| (SOME(RequestReply req)) => loop (doRequestReply (req, arg))
| (SOME(RequestReplies req)) =>
loop (doRequestReplies (req, arg))
| (SOME(RequestExposures req)) =>
loop (doRequestExposures (req, arg))
(* end case *))
*)
val res = loop arg in
CML.send(outCh, OutFlush);
res
end
---
The original code is commented out, but will not type check, our fix is
the uncommented out code. Basically we just returned a bool and based
on the bool did the appropriate thing. NJ, will however, compile the
commented out code. Here are the Mlton typecheck errors.
-------
Error: ../../lib/protocol/xio.sml 474.18.
Case object and rules disagree.
object type: [??? option]
rules expect: [req_msg option]
in: case (CML.recvPoll (reqCh)) of (NON ... estExposures (req, arg)))
compilation aborted: parseAndElaborate reported errors
-----
With type anntations on the various variables...
-------
Error: ../../lib/protocol/xio.sml 474.18.
Case object and rules disagree.
object type: [req_msg option]
rules expect: [req_msg option]
in: case (CML.recvPoll (reqCh)) of (NON ... estExposures (req, arg)))
compilation aborted: parseAndElaborate reported errors
------
Another such example in the widgets with no type annotations:
fun handleReq (GetShades c) = let
val rgb = EXB.rgbOfColor c
in
case rgbFind rgb of NONE => allocShade (c,rgb) | s => s
end
--------------------
Error: ../../widgets/util/shade-server.sml 119.19.
Case object and rules disagree.
object type: [{base: Drawing.pen, dark: Drawing.pen, light:
Drawing.pen} option]
rules expect: [{base: Drawing.pen, dark: Drawing.pen, light:
Drawing.pen} option]
in: case rgbFind rgb of (NONE) => (allo ... de (c, rgb)) | (s) => (s)
compilation aborted: parseAndElaborate reported errors
---------------------
If you have any questions please send mail to me and philip, we can
explain anything that might not be clear.
thank you very much!
Luke