Search code examples
c++cwindows64-bitrtx

WaitForSingleObject and Events, unclear behaviour


I wrote two little test applications with Visual Studio 2017 on Windows 10 64 bit with which I wanted to test Events and WaitForSingleObject.

I am also using RTX realtime extensions from intervalzero.

One of my application is written in x64 Code for the windows part, the other in x64 Code for the RTX subsystem.

Now my idea was to Create an event from within RTX 64 and have it signaled 10 times with a given pause time between the signalling:

int _tmain(int argc, _TCHAR * argv[])
{

    RtPrintf("Starte RTX-Applikation\n");
    RtSleep(0);
    HANDLE hEvent = RtCreateEvent(NULL, false, false, _T("flexLZSStart"));
    if (hEvent != INVALID_HANDLE_VALUE)
    {
        RtPrintf("Event erzeugt\n");
        for (size_t i = 0; i < 10 ; i++)
        {
                RtSetEvent(hEvent);
                RtPrintf("Event gesetzt\n");
                RtSleep(1500);
        }
        RtCloseHandle(hEvent);
    }

    RtPrintf("exit process\n");
    return 0;
}

On the other hand the windows application checks for the creation of the event and then checks repeatedly if the event is signalled:

int main()
{
    Sleep(150);
    HANDLE hEvent = NULL;
    DWORD dwstart = GetTickCount();
    printf("wait for creation of event\n");
    while (hEvent == NULL)
    {
        hEvent = RtOpenEvent(NULL, NULL, _T("flexLZSStart"));
    }
    if ((hEvent == INVALID_HANDLE_VALUE) || (hEvent == NULL))
    {
        exit(-2);
    }
//#define REOPEN
    if ((hEvent != INVALID_HANDLE_VALUE) && (hEvent != NULL))
    {
        DWORD dwErg;
        BOOLEAN aborted = false;
        printf("Event has been created.\n");
#ifdef REOPEN
        RtCloseHandle(hEvent);
#endif
        do
        {
            printf("Wait for event to be signaled\n");
#ifdef REOPEN
            hEvent = RtOpenEvent(NULL, NULL, _T("flexLZSStart"));
            if (hEvent == NULL)
            {
                printf("Event has been disposed?\n");
                break;
            }
#endif
            dwErg = RtWaitForSingleObject(hEvent,1000);
#ifdef REOPEN
            RtCloseHandle(hEvent);
#endif
            DWORD dwLastError = GetLastError();
            if (dwLastError != 0)
            {
                printf("GetLastError returned %d!\n", dwLastError);
            }
            switch (dwErg)
            {
            case WAIT_OBJECT_0:
                printf("received Event\n");
                RtResetEvent(hEvent);
                break;
            case WAIT_TIMEOUT:
                //printf("event not yet received\n");
                break;
            case WAIT_ABANDONED:
            {
                printf("owner of event has been killed\n");
                aborted = true;
            }
            break;
            default:
            {
                printf("no valid return value: %d\n", dwErg);
                aborted = true;
            }
            break;
            }
        } while (!aborted);

    }
    printf("loop exited\n");
    exit(0);
}

Now my observation is, that the RTX code runs through fine, and exits after having signaled the event 10 times.

On the other hand the windows code receives the event 10 times, but it doesnt detect when the rtx application closed the event.

If I compile the code with REOPEN defined, the windows code exits with the 11. open of the event, because it is no more available.

I should enhance my code by having a second event, that is triggered by the windows code after it received the first event, so that the rtx code waits until the windows code has finished its work.

But my final question is:

What is the propper way to detect if the source of the event is still valid?

Can I detect, that the rtx code has created the event, but not yet signalled it, before it eventually has exited?


Solution

  • Due to how I programmed both of my applications, there is no way to detect that the sender has ended.

    To detect this, I should have implemented another mutex that gets fired when the sender exits. So the receiver can detect the signaled mutex and exit himself.