Services & Resources / Wolfram Forums / MathGroup Archive
-----

MathGroup Archive 2012

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

Search the Archive

Concurrency issues with callback functions through MathLink (KernelLink)

  • To: mathgroup at smc.vnet.net
  • Subject: [mg126420] Concurrency issues with callback functions through MathLink (KernelLink)
  • From: Adam Csapo <csapo.adam at gmail.com>
  • Date: Wed, 9 May 2012 03:51:02 -0400 (EDT)
  • Delivered-to: l-mathgroup@mail-archive0.wolfram.com

Hello,

I am developing an application that consists of a Mathematica package and an external Java program. The purpose of the application is to read streamed data from a port and update a variable in the Mathematica package through a callback function.

The callback scheme works using ImplementJavaInterface and the possibility to pass objects as references through MathLink. After the connection is established, the given variable is updated in Mathematica as expected. In the meantime, the notebook that uses the package (and sees the updated variable) does not noticeably block, and I can perform other operations while the variable is updated "in the background".

However, a problem occurs whenever I call the help function (e.g., ?Plot, or ?anything). Sometimes the call goes through and returns the help text. On other occasions, the help text is returned, but as a side effect the link between Mathematica and the external Java program is broken, and I get a message such as:

LinkObject::linkd: Unable to communicate with closed link LinkObject[RealTimeLink,49,17].

The Java program prints the following message when it crashes: "Exception in thread "main" java.lang.reflect.UndeclaredThrowableException at $Proxy0.onDataArrival(Unknown Source)... Caused by: MathLinkException: 1: MathLink connection was lost"

It seems as if the help function is running into concurrency issues, and breaks the link. It is interesting that I have only found this to happen with help, other functions (even ones that take relatively long to evaluate) run fine. I would be grateful for any leads on this issue, as I can't see the relationship between help and the LinkObject I previously establish.

Here are some details on the implementation:

When initializing the Mathematica package, the Java program is started, and it creates two KernelLinks like so:

String[] argstopass = {"-linkmode", "listen", "-linkname", "RealTimeLink"};
String[] argstopass2 = {"-linkmode", "listen", "-linkname", "CommandLink"};
datalink = MathLinkFactory.createKernelLink(argstopass);
commandlink = MathLinkFactory.createKernelLink(argstopass2);

Afterwards, the Mathematica package connects to the two listening links, and the Java program sends an event handler object to Mathematica by reference (in so-called MathLink mode). This allows Mathematica to attach a listener to the object (using ImplementJavaInterface):

datalink.enableObjectReferences();
datalink.discardAnswer();
datalink.putFunction("EvaluatePacket", 1);
datalink.putFunction("InitializeStreamListener", 1);
datalink.putReference(eh); //this is the event handler object
datalink.endPacket();
datalink.discardAnswer();
datalink.evaluate("$ParentLink = First[Links[]];"); //this is called to exit MathLink mode, ensuring that the kernel now listens to the frontend again...

On the Mathematica side, this is what the beginning of InitializeStreamListener[] looks like:

InitializeStreamListener[input_] := Module[{},
streamListenerInterface = ImplementJavaInterface["StreamListenerInterface",{"onDataArrival"->"StreamDataArrived"}];
input@addListenerObject[streamListenerInterface];

After this initialization, the Java program runs in an indefinite loop, while periodically checking for any commands through CommandLink (for example, to quit), and if necessary (when an interesting event occurs) invoking eh. notifyEventListener(), which in turn calls the onDataArrival function of the interface that is implemented in Mathematica. The function updates the variable.

Perhaps I should note that RealTimeLink in Mathematica (above) corresponds to the datalink KernelLink which is created in Java. It is curious that it is always this link that is broken (I suppose because it is the only one that is active, invoking the callback function at least once every second).

I have also tried all kinds of things, with StdLink class, using requestTransaction(), etc, but to no avail.  Am I on the wrong track?

Thank you in advance.




  • Prev by Date: Re: New to Mathematica
  • Next by Date: Mathematica CDF into an iPad iBook
  • Previous by thread: Re: Problem Importing web site in Mathematica: How to by pass pages asking for login credentials
  • Next by thread: Mathematica CDF into an iPad iBook