12

I just found that such MathLink functions as LinkWrite and LinkRead have something like its own internal CheckAbort that absorbs any 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[10]]];
{LinkRead[link], Print["!!"]}

After evaluating the above code press Alt+. and you will get the following output:

During evaluation of In[6]:= !!
Out[9]= {ReturnPacket[$Aborted], Null}

As you see the abort 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?

Trikaldarshiii
  • 11,174
  • 16
  • 67
  • 95
Alexey Popkov
  • 9,355
  • 4
  • 42
  • 93

1 Answers1

1

The way MathLink works, LinkRead blocks if there is nothing to read on the link. If you try to abort at this time, an abort message is passed via MathLink message channel to the other end of the link. If the program on the other end behaves nicely, it will drop whatever it was doing and send a return value (in many cases $Aborted). If you want to propagate the abort to your end of the link, so that you can catch it with CheckAbort, you will need to check the return value and generate another abort, for example:

 If[LinkRead[link] == $Aborted, Abort[]]

This works if you know that the other end of the link returns $Aborted in case it is aborted.

mhavu
  • 41
  • 7
  • When at the other end of the link is MathKernel, can be I sure that it will always return `$Aborted` when `LinkRead` passes it an abort message? Is this behavior reliable? – Alexey Popkov Nov 20 '14 at 16:30
  • 1
    As far as I know, MathKernel always returns `$Aborted` if the evaluation is aborted. However, an abort message might not always abort the evaluation before the evaluation finishes. In these cases a valid result is returned. – mhavu Nov 20 '14 at 16:44
  • So there are two situations: 1. The evaluation is aborted and `$Aborted` is returned; 2. The abort is absorbed without any effect. In the latter situation, is it possible to quit the kernel at the other end of the link without quitting the master kernel? – Alexey Popkov Nov 20 '14 at 16:59
  • 1
    If `LinkRead` is blocking on your end, and you close the link from the remote end, `LinkRead` returns `$Failed`. If the remote kernel is quit gracefully, it will close the link for you. If you kill the remote kernel, `LinkRead` should still return `$Failed`, but I'm not sure whether you can trust that to happen every time. – mhavu Nov 20 '14 at 22:44
  • It looks like we cannot rely on the behavior of both `LinkRead` and the remote kernel. As I see it, the key problem is that we cannot intercept the abort in the master kernel: being able to do this we would have many ways to close the remote kernel or send it an interrupt message or kill it. – Alexey Popkov Nov 20 '14 at 23:03
  • Up to this time I was forced to use the following workaround: do not go into the `LinkRead` blocking but instead use `LinkReadyQ` 10 times per second for checking the state of the remote kernel. This workaround suffer from the same problem: if the abort appears while `LinkReadyQ` is executed, it will be absorbed and will not be intercepted in the master kernel. With `LinkReadyQ` this happens rarely, but I am still unhappy with this workaround. – Alexey Popkov Nov 20 '14 at 23:04
  • If you operate the kernel directly, instead of through the notebook interface, it is possible to send the abort directly to the master kernel or even kill the remote kernel so that `LinkRead` reliably returns `$Failed`. Is this an option for you? – mhavu Nov 21 '14 at 09:45
  • My goal is to stop evaluation completely when a user generates abort. The ideal solution would go through the steps: 1) try to abort the remote kernel then 2) kill it if it does not respond and finally 3) abort evaluation in the master kernel. Of course manual closing the remote kernel by means of the OS is possible but I would like to avoid doing so. – Alexey Popkov Nov 21 '14 at 10:40
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/65355/discussion-between-mhavu-and-alexey-popkov). – mhavu Nov 21 '14 at 10:54