Re: Alarm signal and recv system call
Matthew Fluet <[email protected]> Thu, 15 Nov 2018 21:14:07 -0500
| Newsgroups | gmane.comp.lang.ml.mlton.user |
|---|---|
| Message-ID | <CAMrhFL7ObKCQLZ0Hbcoe0uj=QmJ+hc74ZyegCHuOHY6T3DZRcg@mail.gmail.com> |
--===============7506386836349485545== Content-Type: multipart/alternative; boundary="000000000000837ea9057abeb9a9" --000000000000837ea9057abeb9a9 Content-Type: text/plain; charset="UTF-8" On Thu, Nov 15, 2018 at 6:43 PM Henry Cejtin <[email protected]> wrote: > 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. > Here's the behavior I see with your program: [matthew@shadow tmp]$ mlton MLton 20180207 [matthew@shadow tmp]$ mlton z.sml [matthew@shadow tmp]$ ./z Waiting: ^CGot signaled That's what I would expect from your program. Your signal handler performs `OS.Process.exit OS.Process.failure`, so it never returns from the signal handler to the "restart or raise" wrapper around the system call: "If a system call is interrupted by a signal, then the signal handler will run before the call is restarted or OS.SysError is raised; that is, before the Signal.restart check." (http://mlton.org/MLtonSignal) > 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? > No. A MLton.Thread.Runnable.t is really just the suspended stack, possibly suspended at any (GC safe) point by a signal. I don't think there is any good way to run "new" code on that stack, although the parasitic threads that Suresh and Lukasz implemented seems to have done something like that. > I can definitely imagine that this may have been forbidden because it > would cause the control flow analysis to violate assumptions. > Right (or, one would need to assume that any exception could be thrown from any point). 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? > I don't know if it is a bad idea, but it isn't one that MLton currently supports. -Matthew > 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 filled), 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]. > > > > _______________________________________________ > 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]. --000000000000837ea9057abeb9a9 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr"><div dir=3D"ltr"><div dir=3D"ltr"><div dir=3D"ltr"><div cl= ass=3D"gmail_default" style=3D"font-family:"courier new",monospac= e;font-size:large"><span style=3D"font-family:Arial,Helvetica,sans-serif;fo= nt-size:small">On Thu, Nov 15, 2018 at 6:43 PM Henry Cejtin <<a href=3D"= mailto:[email protected]">[email protected]</a>> wrote:</span>= <br></div><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" styl= e=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);paddin= g-left:1ex">The=C2=A0 behavior I see when I set MLton.Signal.restart to fal= se is not that<br> OS.SysError is raised, but that the program immediately exits (with exit<br= > status 1).<br> <br> Here is the code.<br> <br> =3D=3D=3D=3D=3D=3D<br> val () =3D MLton.Signal.restart :=3D false<br> fun sh () =3D let val () =3D print "Got signaled\n"<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 in OS.Process.exit OS.Process.fai= lure<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 end<br> val _ =3D MLton.Signal.setHandler<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(<a href=3D"http://Posix.Signal.in= t" rel=3D"noreferrer" target=3D"_blank">Posix.Signal.int</a>,<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 MLton.Signal.Handler.simple sh)<b= r> val _ =3D print "Waiting:\n"<br> val msg =3D (case TextIO.inputLine TextIO.stdIn of<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0NONE =3D> "*** EOF = ***"<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0| SOME msg =3D> msg)<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 handle e =3D> (print ("inputLine= raised "<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0^ exnName e<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0^ ", with message "<= br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0^ exnMessage e<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0^ "\n");<br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0raise Fail "Deadly raise from inputLine")<br> val _ =3D print ("Got " ^ msg ^ "\n")<br> =3D=3D=3D=3D=3D=3D<br> <br> When=C2=A0 run,=C2=A0 if=C2=A0 I hit control-C after seeing the Waiting: pr= ompt it just<br> exists.=C2=A0 I would have expected to the print in the handle to be run.<b= r></blockquote><div><br></div><div><div class=3D"gmail_default" style=3D"fo= nt-family:"courier new",monospace;font-size:large">Here's the= behavior I see with your program:</div><div class=3D"gmail_default" style= =3D"font-family:"courier new",monospace;font-size:large"><br></di= v><div class=3D"gmail_default" style=3D"font-family:"courier new"= ,monospace;font-size:large">[matthew@shadow tmp]$ mlton</div><div class=3D"= gmail_default" style=3D"font-family:"courier new",monospace;font-= size:large">MLton 20180207</div><div class=3D"gmail_default" style=3D"font-= family:"courier new",monospace;font-size:large">[matthew@shadow t= mp]$ mlton z.sml</div><div class=3D"gmail_default" style=3D"font-family:&qu= ot;courier new",monospace;font-size:large">[matthew@shadow tmp]$ ./z</= div><div class=3D"gmail_default" style=3D"font-family:"courier new&quo= t;,monospace;font-size:large">Waiting:</div><div class=3D"gmail_default" st= yle=3D"font-family:"courier new",monospace;font-size:large">^CGot= signaled</div><div class=3D"gmail_default" style=3D"font-family:"cour= ier new",monospace;font-size:large"></div><div class=3D"gmail_default"= style=3D"font-family:"courier new",monospace;font-size:large">Th= at's what I would expect from your program.=C2=A0 Your signal handler p= erforms `OS.Process.exit OS.Process.failure`, so it never returns from the = signal handler to the "restart or raise" wrapper around the syste= m call: "If a system call is interrupted by a signal, then the signal = handler will run before the call is restarted or OS.SysError is raised; tha= t is, before the Signal.restart check." (<a href=3D"http://mlton.org/M= LtonSignal">http://mlton.org/MLtonSignal</a>)</div></div><div>=C2=A0</div><= blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-l= eft:1px solid rgb(204,204,204);padding-left:1ex"> On a rather=C2=A0 unrelated=C2=A0 note,=C2=A0 is=C2=A0 there=C2=A0 any=C2= =A0 way=C2=A0 to=C2=A0 prepend=C2=A0 (as=C2=A0 in<br> MLton.Thread.prepend)=C2=A0 =C2=A0 to=C2=A0 =C2=A0 a=C2=A0 =C2=A0 MLton.Run= nable.t=C2=A0 =C2=A0(instead=C2=A0 =C2=A0of=C2=A0 =C2=A0a<br> MLton.Thread.t?=C2=A0 I.e., can I insert some code to be run in=C2=A0 the= =C2=A0 handler<br> context of a runnable?<br></blockquote><div><br></div><div><div class=3D"gm= ail_default" style=3D"font-family:"courier new",monospace;font-si= ze:large">No.=C2=A0 A MLton.Thread.Runnable.t is really just the suspended = stack, possibly suspended at any (GC safe) point by a signal.=C2=A0 I don&#= 39;t think there is any good way to run "new" code on that stack,= although the parasitic threads that Suresh and Lukasz implemented seems to= have done something like that.</div></div><div>=C2=A0</div><blockquote cla= ss=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid = rgb(204,204,204);padding-left:1ex"> I=C2=A0 can=C2=A0 definitely=C2=A0 imagine that this may have been forbidde= n because it<br> would cause the control flow analysis to violate assumptions.<br></blockquo= te><div><br></div><div><div class=3D"gmail_default" style=3D"font-family:&q= uot;courier new",monospace;font-size:large">Right (or, one would need = to assume that any exception could be thrown from any point).</div></div><d= iv><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px = 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> The connection is that if one could do that, it would be a way to insert<br= > the raising of an exception in the signal handler.</blockquote><blockquote = class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px sol= id rgb(204,204,204);padding-left:1ex"> Perhaps that would be a bad idea anyway?<br></blockquote><div><br></div><di= v><div class=3D"gmail_default" style=3D"font-family:"courier new"= ,monospace;font-size:large">I don't know if it is a bad idea, but it is= n't one that MLton currently supports.</div><div class=3D"gmail_default= " style=3D"font-family:"courier new",monospace;font-size:large"><= br></div><div class=3D"gmail_default" style=3D"font-family:"courier ne= w",monospace;font-size:large">-Matthew</div><br></div><div>=C2=A0</div= ><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border= -left:1px solid rgb(204,204,204);padding-left:1ex"> On Thu, Nov 15, 2018 at 3:58 PM Matthew Fluet <<a href=3D"mailto:matthew= [email protected]" target=3D"_blank">[email protected]</a>> wrote:<= br> ><br> > In addition to Henry's comments, there is a little more to the sto= ry.=C2=A0 It is true that at the libc level, an interrupted system call wil= l typically return immediately with -1 and errno set to EINTR.=C2=A0 MLton&= #39;s implementation of the Basis Library chooses to restart most such libc= functions.=C2=A0 However, this is configurable via `val MLton.Signal.resta= rt : bool ref`.=C2=A0 See the "Interruptible System Calls" sectio= n of <a href=3D"http://mlton.org/MLtonSignal" rel=3D"noreferrer" target=3D"= _blank">http://mlton.org/MLtonSignal</a>.=C2=A0 The default (of restarting = system calls) makes sense for some uses of signals (e.g., profiling or aski= ng a long-running program to save state in response to a periodic signal).= =C2=A0 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 filled), so it may be almost impossible to han= dle the OS.SysError exception and resume so that no output is lost.<br> ><br> > On Thu, Nov 15, 2018 at 11:32 AM Henry Cejtin <<a href=3D"mailto:he= [email protected]" target=3D"_blank">[email protected]</a>> wrot= e:<br> >><br> >> You=C2=A0 have=C2=A0 to=C2=A0 remember=C2=A0 that=C2=A0 MLton=C2= =A0 signal=C2=A0 handlers=C2=A0 are running in a<br> >> separate thread.=C2=A0 It gets passed the thread=C2=A0 that=C2=A0 = was=C2=A0 interrupted=C2=A0 and<br> >> returns=C2=A0 the=C2=A0 thread to run when the handler is finished= .=C2=A0 The result of<br> >> Handler.simple returns the thread it was called with, and hence re= starts<br> >> the interrupted thread.<br> >><br> >> If=C2=A0 you=C2=A0 want the Socket.recvVec (or whatever) to be `ab= orted', then you<br> >> can't use Handler.simple to make the handler.=C2=A0 Instead yo= u have to=C2=A0 have<br> >> some=C2=A0 other=C2=A0 thread to resume, or, if you want the progr= am to terminate,<br> >> you have to terminate it in the handler.=C2=A0 You can do=C2=A0 th= e=C2=A0 latter=C2=A0 with,<br> >> for example, OS.Process.exit.<br> >><br> >> Doing this, your sample program would look like this:<br> >><br> >>=C2=A0 =C2=A0 =C2=A0fun h =3D let val () =3D print "Alarm sig\= n"<br> >>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0in OS.Process.exit = OS.Process.failure<br> >>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0end<br> >>=C2=A0 =C2=A0 =C2=A0val () =3D MLton.Signal.setHandler (Posix.Signa= l.arm,<br> >>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0ML= ton.Signal.Handler.simple h)<br> >>=C2=A0 =C2=A0 =C2=A0val () =3D Posix.Process.Alarm (Time.fromSecond= s (Int.toLarge 3))<br> >>=C2=A0 =C2=A0 =C2=A0val r =3D Socket.recvVec (socket, 1024)<br> >>=C2=A0 =C2=A0 =C2=A0val () =3D print "Done\n"<br> >> On Thu, Nov 15, 2018 at 5:54 AM Kostirya <<a href=3D"mailto:kos= [email protected]" target=3D"_blank">[email protected]</a>> wrote:<br> >> ><br> >> > I was surprised to find that Alarm signal do not abort recvVe= c function.<br> >> > How is this possible?<br> >> > I thought recv was always aborted on signal.<br> >> ><br> >> ><br> >> > I use for test:<br> >> ><br> >> > val _ =3D MLton.Signal.setHandler(Posix.Signal.alrm,<br> >> > MLton.Signal.Handler.simple (fn _ =3D> print "Alarm s= ig\n"))<br> >> > val _ =3D Posix.Process.alarm (Time.fromSeconds (Int.toLarge = 3))<br> >> > val r =3D Socket.recvVec (socket, 1024)<br> >> > val _ =3D print "Done\n"<br> >> ><br> >> > --<br> >> > You received this message because you are subscribed to the G= oogle Groups "MLton-user" group.<br> >> > To unsubscribe from this group and stop receiving emails from= it, send an email to <a href=3D"mailto:mlton-user%[email protected]"= target=3D"_blank">[email protected]</a>.<br> >> ><br> >> ><br> >> ><br> >> > _______________________________________________<br> >> > MLton-user mailing list<br> >> > <a href=3D"mailto:[email protected]" target=3D= "_blank">[email protected]</a>; <a href=3D"mailto:mlton-user= @mlton.org" target=3D"_blank">[email protected]</a><br> >> > <a href=3D"https://lists.sourceforge.net/lists/listinfo/mlton= -user" rel=3D"noreferrer" target=3D"_blank">https://lists.sourceforge.net/l= ists/listinfo/mlton-user</a><br> >><br> >> --<br> >> You received this message because you are subscribed to the Google= Groups "MLton-user" group.<br> >> To unsubscribe from this group and stop receiving emails from it, = send an email to <a href=3D"mailto:mlton-user%[email protected]" targ= et=3D"_blank">[email protected]</a>.<br> >><br> >><br> >><br> >> _______________________________________________<br> >> MLton-user mailing list<br> >> <a href=3D"mailto:[email protected]" target=3D"_bla= nk">[email protected]</a>; <a href=3D"mailto:mlton-user@mlto= n.org" target=3D"_blank">[email protected]</a><br> >> <a href=3D"https://lists.sourceforge.net/lists/listinfo/mlton-user= " rel=3D"noreferrer" target=3D"_blank">https://lists.sourceforge.net/lists/= listinfo/mlton-user</a><br> ><br> > --<br> > You received this message because you are subscribed to the Google Gro= ups "MLton-user" group.<br> > To unsubscribe from this group and stop receiving emails from it, send= an email to <a href=3D"mailto:mlton-user%[email protected]" target= =3D"_blank">[email protected]</a>.<br> > _______________________________________________<br> > MLton-user mailing list<br> > <a href=3D"mailto:[email protected]" target=3D"_blank">= [email protected]</a>; <a href=3D"mailto:[email protected]= g" target=3D"_blank">[email protected]</a><br> > <a href=3D"https://lists.sourceforge.net/lists/listinfo/mlton-user" re= l=3D"noreferrer" target=3D"_blank">https://lists.sourceforge.net/lists/list= info/mlton-user</a><br> <br> -- <br> You received this message because you are subscribed to the Google Groups &= quot;MLton-user" group.<br> To unsubscribe from this group and stop receiving emails from it, send an e= mail to <a href=3D"mailto:mlton-user%[email protected]" target=3D"_bl= ank">[email protected]</a>.<br> <br> <br> <br> _______________________________________________<br> MLton-user mailing list<br> <a href=3D"mailto:[email protected]" target=3D"_blank">MLton= [email protected]</a>; <a href=3D"mailto:[email protected]" ta= rget=3D"_blank">[email protected]</a><br> <a href=3D"https://lists.sourceforge.net/lists/listinfo/mlton-user" rel=3D"= noreferrer" target=3D"_blank">https://lists.sourceforge.net/lists/listinfo/= mlton-user</a><br> </blockquote></div></div></div></div></div> <p></p> -- <br /> You received this message because you are subscribed to the Google Groups &= quot;MLton-user" group.<br /> To unsubscribe from this group and stop receiving emails from it, send an e= mail to <a href=3D"mailto:[email protected]">mlton-user+unsu= [email protected]</a>.<br /> --000000000000837ea9057abeb9a9-- --===============7506386836349485545== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline --===============7506386836349485545== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ MLton-user mailing list [email protected]; [email protected] https://lists.sourceforge.net/lists/listinfo/mlton-user --===============7506386836349485545==--