MathGroup Archive 2011

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: CheckAbort inside MathLink functions?

  • To: mathgroup at smc.vnet.net
  • Subject: [mg118141] Re: CheckAbort inside MathLink functions?
  • From: "Alexey Popkov" <lehin.p at gmail.com>
  • Date: Thu, 14 Apr 2011 04:48:59 -0400 (EDT)
  • References: <000501cbf98b$537aacb0$bc0a440a@lehin> <201104131837.p3DIbT6e026930@wolfram.com>

Todd,

Thank you for the responce.

But I have two problems with your solution.

The first one is that ReturnPacket[$Aborted] could not be distinguished from
the same packet returned as the result of internal abort inside the code in
the slave kernel:
LinkWrite[link, Unevaluated[Abort[]]]
This problem remains when using EvaluatePacket and EnterExpressionPacket.

I wish to treat user-generated aborts in a different way than those
generated by a program currently evaluating in the slave kernel. Is there a
way to distinguish them?

And another problem is with LinkWrite. There is a case when your solution
does not work. It happens when a user press Alt+"." at the time of
evaluating of LinkWrite:

In[13]:= list=RandomReal[{0,1},1000001];
CheckAbort[AbortProtect[link=LinkLaunch[First[$CommandLine]<>" -mathlink"];LinkRead[link];With[{list=list},LinkWrite[link,Unevaluated[list.list]]];If[(result=LinkRead[link])===ReturnPacket[$Aborted],Abort[],Print[result]]],Print["!!"]]
LinkClose[link]

During evaluation of In[13]:= LinkObject::linkw: Unable to write data to
closed link LinkObject[MathKernel -mathlink,12,8].
During evaluation of In[13]:= LinkObject::linkd: Unable to communicate with
closed link LinkObject[MathKernel -mathlink,12,8].
During evaluation of In[13]:= $Failed
During evaluation of In[13]:= LinkObject::linkn: Argument
LinkObject[MathKernel -mathlink,12,8] in
LinkClose[LinkObject[MathKernel -mathlink,12,8]] has an invalid LinkObject
number; the link may be closed. >>
Out[15]= LinkClose[LinkObject[MathKernel -mathlink,12,8]]

The above Messages appear sometimes when I press Alt+"." after evaluating
this code. It seems that LinkWrite closes the 'link' when Alt+"." was
pressed during its evaluation. As the result, a couple of error messages
appear. How to handle such situations correctly?

Alexey


----- Original Message ----- 
From: "Todd Gayley" <tgayley at wolfram.com>
To: "Alexey Popkov" <lehin.p at gmail.com>; "comp.soft-sys.math.mathematica"
<mathgroup at smc.vnet.net>
Sent: Wednesday, April 13, 2011 11:37 PM
Subject: [mg118141] Re: CheckAbort inside MathLink functions?


> At 10:31 PM 4/12/2011, Alexey Popkov wrote:
> >Hello,
> >
> >It seems that that such MathLink functions as LinkWrite and LinkRead have
> >something like its own internal CheckAbort that absorbs user-generated
> >aborts, and does not propagate them further.
> >
> >This can be easily shown with LinkRead:
> >
> >link = LinkLaunch[First[$CommandLine] <> " -mathlink"];
> >LinkRead[link];
> >LinkWrite[link, Unevaluated[Pause[100]]];
> >CheckAbort[AbortProtect[Print[LinkRead[link]]], Print["!!"]]
> >
> >If we press Alt+. after evaluating the above code we get only the
following
> >output:
> >
> >During evaluation of In[6]:= ReturnPacket[$Aborted]
> >
> >But Print["!!"] is not evaluated although we have generated Abort[]
exactly
> >inside CheckAbort.
> >
> >One can see that the abort we made by pressing Alt+. was absorbed by
> >LinkRead.
> >
> >My problem is that it breaks my own flow control of evaluation based on
> >CheckAbort.
> >
> >Is there a way to intercept aborts absorbed by such functions as LinkRead
> >and LinkWrite for having ability to catch user-generated aborts?
>
>
> Alexey,
>
> The behavior you describe is a feature, and writing correct
> Mathematica programs that call external programs via MathLink would
> be difficult without it. The behavior you have discovered is this: If
> a user abort is detected while the kernel is blocking in a LinkRead
> call, the abort is not handled like a normal abort request, but
> instead it is propagated to the external program (specifically, a
> MathLink MLAbortMessage is sent over the link that the kernel is reading
from).
>
> To see why this is useful, consider the following pseudocode user
> program that calls an external program via MathLink:
>
>      LinkWrite[link, something];
>      While[haventReceivedFinalPacket,
>          LinkRead[link]
>      ]
>
> Consider what happens if a user of this program hits Alt-. to trigger
> an abort while it is running, say between calls to LinkRead. The
> kernel will exit from the While loop, leaving unread packets on the
> link. The external program is now effectively broken, because future
> attempts to use it will end up reading packets left over from the
> previous call.
>
> The correct way to fix this is to wrap the entire operation in
> AbortProtect, making it atomic. Once you start an transaction with
> the external program, there is no way the user can inadvertently
> prevent it from finishing by requesting an abort at an inopportune time.
>
>      AbortProtect[
>          LinkWrite[link, something];
>              While[haventReceivedFinalPacket,
>              LinkRead[link]
>          ]
>      ]
>
> We have now fixed a bug in our program by making sure it won't break
> horribly if a user tries to abort it. But what we really want is to
> honor the user's request for an abort. As we've just discussed, we
> cannot do this by simply backing out of a LinkRead. The sensible
> thing is for LinkRead to forward the abort request to the external
> program in the hopes that the external program will pay attention to
> it. After all, the external program "owns" the computation at this
> point. MathLink programs have a means of detecting abort messages
> arriving over the link, and can clean up and return an appropriate result.
>
> For all this to work properly, AbortProtect must not prevent LinkRead
> from forwarding the abort, and it does in fact behave this way.
>
> In the case of your program, Alexey, this behavior is not "breaking
> your flow control", it is absolutely required to avoid problems. When
> you execute the program you showed, and hit Alt-. and get back
> ReturnPacket[$Aborted], you are seeing the behavior I described
> above. The abort is forwarded to the slave kernel, which aborts its
> evaluation of Pause[100] and returns $Aborted. If you want to have
> the Alt-. propagate all the way back up to abort the entire top-level
> program that was executing, which is typically the right behavior,
> what you need to do is look for $Aborted returning from the slave
> kernel and then call Abort[] yourself:
>
>      AbortProtect[
>          LinkWrite[link, Unevaluated[Pause[100]]];
>          result = LinkRead[link];
>          If[result === ReturnPacket[$Aborted],
>              (* Re-fire the Abort, which will trigger as soon as the
> AbortProtect block ends. *)
>              Abort[]
>          ]
>      ]
>
> If you want to use CheckAbort to catch the re-fired Abort, that will work
fine.
>
>
> --Todd
>
>



  • Prev by Date: Re: CheckAbort inside MathLink functions?
  • Next by Date: Re: irritating behaviour of the interface (Mathematica 8.0.0, Ubuntu
  • Previous by thread: Re: CheckAbort inside MathLink functions?
  • Next by thread: Re: Workbench question: Is there a $WorkbenchCurrentWorkingDirectory