7

What is the simplest way to throw away all expressions waiting to be read on a loopback link, effectively resetting the link?

I am building an expression on a loopback link using the C MathLink interface. If the operation succeeds, I want to send the expression to stdlink. If it fails, I need to clear the loopback link. What is the recommended way to do this?

Szabolcs
  • 234,956
  • 30
  • 623
  • 1,263

1 Answers1

9

Using NULL as the destination link, as in MLTransferExpression(NULL, loop); is indeed the "correct" way to do this.

One small caveat: You cannot use that technique if you have not built a complete expression on the loopback link. For example, if you are building a complicated expression on the loopback link bit by bit, then decide halfway through to bail out and not use the result you have been building, then you would just want to close the loopback link to discard it. A simple example:

// Promise to put 100 elements:
MLPutFunction(loop, "List", 100);
int succeeded = TRUE;
for (int i = 0; i < 100; i++) {
    ...
    if (someTest) {
        succeeded = FALSE;
        // Bail out before putting all 100 promised elements.
        break;
    } else {
       MLPutInteger(loop, someInt);
    }
}

if (succeeded) {
    MLTransferExpression(stdlink, loop);
} else {
    // *** BAD ***  Haven't put a complete expression on the link,
    // so this will not work to drain the link:
    MLTransferExpression(NULL, loop);
    ... send different result on stdlink
}

If you are doing something like the above, it's better to accumulate the parts of the final expression on the link as separate expressions, then wait until the loop is done to build the final expression:

int count = 0;
for ( ; count < 100; count++) {
    ...
    if (someTest) {
        break;
    } else {
       MLPutInteger(loop, someInt);
    }
}

if (count == 100) {
    // Loop ran to completion; send a list containing all the elements
    // that were stored on the loopback link.
    MLPutFunction(stdlink, "List", 100);
    MLTransferToEndOfLoopbackLink(stdlink, loop);
} else {
    ... send different result on stdlink
}

In this way, you never have a partial expression on the loopback link.

But you can avoid all these considerations by simply opening and closing your loopback link every time your function is called. This could have an impact on performance if your function runs very quickly and is called many times. It costs about .00001 seconds on my machine to open and close a loopback link.

halirutan
  • 112,764
  • 7
  • 263
  • 474
Todd Gayley
  • 4,198
  • 20
  • 19
  • 1
    It sounds like I need to close/open the link then because I have half-built expressions. The performance hit is acceptable in this case. – Szabolcs Jan 28 '13 at 20:38