Re: Alarm signal and recv system call
Henry Cejtin <[email protected]> Thu, 15 Nov 2018 17:42:31 -0600
| Newsgroups | gmane.comp.lang.ml.mlton.user |
|---|---|
| Message-ID | <CAPKXxCq7A+d+xh_R4KWD=_wwsYTWPZaevPZGASo7KKSrzXGLyA@mail.gmail.com> |
The behavior I see when I set MLton.Signal.restart to false is not that
OS.SysError is raised, but that the program immediately exits (with exit
status 1).
Here is the code.
======
val () = MLton.Signal.restart := false
fun sh () = let val () = print "Got signaled\n"
in OS.Process.exit OS.Process.failure
end
val _ = MLton.Signal.setHandler
(Posix.Signal.int,
MLton.Signal.Handler.simple sh)
val _ = print "Waiting:\n"
val msg = (case TextIO.inputLine TextIO.stdIn of
NONE => "*** EOF ***"
| SOME msg => msg)
handle e => (print ("inputLine raised "
^ exnName e
^ ", with message "
^ exnMessage e
^ "\n");
raise Fail "Deadly raise from inputLine")
val _ = print ("Got " ^ msg ^ "\n")
======
When run, if I hit control-C after seeing the Waiting: prompt it just
exists. I would have expected to the print in the handle to be run.
On a rather unrelated note, is there any way to prepend (as in
MLton.Thread.prepend) to a MLton.Runnable.t (instead of a
MLton.Thread.t? I.e., can I insert some code to be run in the handler
context of a runnable?
I can definitely imagine that this may have been forbidden because it
would cause the control flow analysis to violate assumptions.
The connection is that if one could do that, it would be a way to insert
the raising of an exception in the signal handler.
Perhaps that would be a bad idea anyway?
On Thu, Nov 15, 2018 at 3:58 PM Matthew Fluet <[email protected]> wrote:
>
> In addition to Henry's comments, there is a little more to the story. It is true that at the libc level, an interrupted system call will typically return immediately with -1 and errno set to EINTR. MLton's implementation of the Basis Library chooses to restart most such libc functions. However, this is configurable via `val MLton.Signal.restart : bool ref`. See the "Interruptible System Calls" section of http://mlton.org/MLtonSignal. The default (of restarting system calls) makes sense for some uses of signals (e.g., profiling or asking a long-running program to save state in response to a periodic signal). Also, in the context of high-level operations, performing something like BinIO.output with a very large output vector could result in multiple system calls (as buffers are fille
d), so it may be almost impossible to handle the OS.SysError exception and resume so that no output is lost.
>
> On Thu, Nov 15, 2018 at 11:32 AM Henry Cejtin <[email protected]> wrote:
>>
>> You have to remember that MLton signal handlers are running in a
>> separate thread. It gets passed the thread that was interrupted and
>> returns the thread to run when the handler is finished. The result of
>> Handler.simple returns the thread it was called with, and hence restarts
>> the interrupted thread.
>>
>> If you want the Socket.recvVec (or whatever) to be `aborted', then you
>> can't use Handler.simple to make the handler. Instead you have to have
>> some other thread to resume, or, if you want the program to terminate,
>> you have to terminate it in the handler. You can do the latter with,
>> for example, OS.Process.exit.
>>
>> Doing this, your sample program would look like this:
>>
>> fun h = let val () = print "Alarm sig\n"
>> in OS.Process.exit OS.Process.failure
>> end
>> val () = MLton.Signal.setHandler (Posix.Signal.arm,
>> MLton.Signal.Handler.simple h)
>> val () = Posix.Process.Alarm (Time.fromSeconds (Int.toLarge 3))
>> val r = Socket.recvVec (socket, 1024)
>> val () = print "Done\n"
>> On Thu, Nov 15, 2018 at 5:54 AM Kostirya <[email protected]> wrote:
>> >
>> > I was surprised to find that Alarm signal do not abort recvVec function.
>> > How is this possible?
>> > I thought recv was always aborted on signal.
>> >
>> >
>> > I use for test:
>> >
>> > val _ = MLton.Signal.setHandler(Posix.Signal.alrm,
>> > MLton.Signal.Handler.simple (fn _ => print "Alarm sig\n"))
>> > val _ = Posix.Process.alarm (Time.fromSeconds (Int.toLarge 3))
>> > val r = Socket.recvVec (socket, 1024)
>> > val _ = print "Done\n"
>> >
>> > --
>> > You received this message because you are subscribed to the Google Groups "MLton-user" group.
>> > To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
>> >
>> >
>> >
>> > _______________________________________________
>> > MLton-user mailing list
>> > [email protected]; [email protected]
>> > https://lists.sourceforge.net/lists/listinfo/mlton-user
>>
>> --
>> You received this message because you are subscribed to the Google Groups "MLton-user" group.
>> To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
>>
>>
>>
>> _______________________________________________
>> MLton-user mailing list
>> [email protected]; [email protected]
>> https://lists.sourceforge.net/lists/listinfo/mlton-user
>
> --
> You received this message because you are subscribed to the Google Groups "MLton-user" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
> _______________________________________________
> MLton-user mailing list
> [email protected]; [email protected]
> https://lists.sourceforge.net/lists/listinfo/mlton-user
--
You received this message because you are subscribed to the Google Groups "MLton-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].