LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Can execution of a called DLL be aborted when the caller is aborted?

Solved!
Go to solution

When a VI is caught in an infinite loop, or is processing more data than expected, using the Abort button (or ctrl period) is able to abort execution. However, when using a VI that calls a DLL, the abort signal appears to wait until execution of the DLL is complete. In heavy processing applications such as those using IMAQ, this can lead to severe hang-ups. I'm assuming IMAQ is written in C++, though I am not sure.

 

Is there a way to abort all running processes and their subprocesses? Am I potentially misunderstanding the issue?

 

 

 

LabView 19.0f2

0 Kudos
Message 1 of 4
(980 Views)
Solution
Accepted by topic author Nokaroa

@Nokaroa wrote:

Is there a way to abort all running processes and their subprocesses?


Aborting all processes and subprocesses isn't a problem. This is what task manager does. There's a windows function called KillProcess that does this.

 

The only way to kill specific processes is to start them as process. That means making it an executable, and using Windows APIs to start it. Of course data to and from it needs to be communicated somehow.

 

DLLs used by IMAQ run in the LabVIEW process. They're not "subprocesses" (if there is such a thing), but probably a thread or threads in the process. AFAIK threads can't be aborted without aborting the process, as the aborted dll thread is a LabVIEW thread and that will 'abort' LabVIEW too.

 


@Nokaroa wrote:

Am I potentially misunderstanding the issue?


It doesn't seem like it. You got the problem right and there's no easy solution.

0 Kudos
Message 2 of 4
(959 Views)

@Nokaroa wrote:

When a VI is caught in an infinite loop, or is processing more data than expected, using the Abort button (or ctrl period) is able to abort execution. However, when using a VI that calls a DLL, the abort signal appears to wait until execution of the DLL is complete. In heavy processing applications such as those using IMAQ, this can lead to severe hang-ups. I'm assuming IMAQ is written in C++, though I am not sure.

 

Is there a way to abort all running processes and their subprocesses? Am I potentially misunderstanding the issue?

Wiebe already explained what can be done for standard DLLs. There is nothing I can add there. Theoretically it would be possible to execute everything in a debugger context and then you can interrupt threads to break into, but aborting them is not something that can be done without killing the process that started them. There is no way to guarantee process state consistency if you yank threads out of a process so it is not supported. Threads only can terminate orderly by running to the end of their procedure and are then cleaned up the OS.

 

If you have a chance to modify the DLL, there is a way to allow the LabVIEW process to inform your DLL that it should abort, but it ain't trivial! In the Call Library Node you have the Callback Configuration Tab which allows to set a Reserve, Unreserve and Abort function. Each of these functions takes one parameter, a pointer by reference. Your Reserve function allocates the pointer, the Unreserve function deallocates it and Abort is called with this pointer if you abort the LabVIEW hierarchy. In addition you can configure an additional parameter to be passed to the DLL function which passes in this pointer. What you store in that pointer is up to you. The general idea is that it your DLL function stores some information in there that will allow the Abort function to inform your function to abort whatever it is doing. It could be an event that your DLL function checks regularly while executing, or it could be even just a boolean that initialized to false.

 

 

#include "extcode.h"

struct
{
    int abort;
    int otherData;
} MyInstanceData;

MgErr MyReserve(InstanceDataPtr *ptr)
{
    *ptr = DSNewPClr(sizeof(MyInstanceData));
    return (*ptr) ? noErr : mFullErr;
}

MgErr MyUnreserve(InstanceDataPtr *ptr)
{
    DSDisposePtr(*ptr);
    return noErr;
}

MgErr MyAbort(InstanceDataPtr *ptr)
{
    MyInstanceData *data = (MyInstanceData*)*ptr;
    if (data)
        data->abort = TRUE;
    return noErr;
}

MgErr MyFunction(........, InstanceDataPtr *ptr)
{
    MyInstanceData *data = (MyInstanceData*)*ptr;
    if (data)
    {
         while(!data->abort)
         {
              // do some lengthy processing, once finished return
              .......
              if (finished)
                  return noErr;
         }
         // we got aborted
         return mgErrAborted;
    }
    return mgArgErr;
}

 

 

Rolf Kalbermatter
My Blog
Message 3 of 4
(946 Views)

This is unfortunate. Thank you for the reply. 

0 Kudos
Message 4 of 4
(894 Views)