Multi-Threaded Applications

If you are creating a multi-threaded application, then you must make sure that the following WiT-DLL functions are called only from the main thread:

witDllInit4 (and all older versions: witDllInit3, witDllInit2, witDllInit)
witControlExec (and all older versions: witRunIgr, witControlIgr)
witSetDisplayWnd
witWndRepaint

The reason is that WiT Engine always runs with multiple internal threads. One of these threads handles all operators that require a GUI, such as display and getData, so this must be the main application thread. WiT uses Windows messaging to communicate and synchronize between this thread (the main thread) and the other WiT threads. This communication is kept to a minimum, since Windows messaging is slow. However, the starting and stopping of a WIC program requires the use of Windows messages, even if the WIC program contains no GUI operators.

witControlExec can be called from any thread if the Block parameter is FALSE. But if the Block parameter is TRUE and witControlExec is called from a thread other than the main thread, it will never return because in blocking mode, witControlExec uses an internal loop to get and dispatch Windows messages.

If it is necessary to call witControlExec from a thread other than the main thread in your application, set the Block parameter to FALSE, and register a state callback function using witSetStateCallback. By having appropriate code for the case when the state is EXEC_STOPPED in the callback function, your program can accurately and efficiently handle the end of WIC program execution. One of things you can do is to put a semaphore wait right after the witControlExec call. The semaphore is signaled when the WIC execution state has changed to EXEC_STOPPED. E.g.:

mainThread( )
{
    witDllInit4(...);
    witSetStateCallback(witStateCallback);
    // create wicStoppedSema as binary semaphore with initial value 0
    ...
    // spawn threadCode as thread
    ...
}

threadCode( ) 
{
    while (1) {
        witControlExec(execHandle, WIT_EXE_FLASH, FALSE);
        semaphoreWait(wicStoppedSema);
    }
}

witStateCallback(const ExecState state)
{
    if (state == EXEC_STOPPED)
        semaphoreSignal(wicStoppedSema);
}

Previous 

Up 

Next