0

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?

Wolfgang Roth
  • 451
  • 4
  • 18
  • The proper solution is not to close the event while your program is still using it. It's common sense, really. If you need to shut down multiple threads, you can have an event for that too, then let them finish gracefully on their own before closing the handles. – Lundin Dec 12 '18 at 10:26
  • @Lundin, that's not the point of my question. If the program that created the event crashes without setting the event for another programm to be signalled, i have no chance to see if the event is still valid. Maybe both programs created/opened the event a long time ago the waitforsingleobject could refer to an invalid handle because the creating program has already exited... – Wolfgang Roth Dec 12 '18 at 14:05
  • @WolfgangRoth "*If the program that created the event crashes without setting the event for another programm to be signalled, i have no chance to see if the event is still valid*" - Kernel objects, like events, are reference counted. As long as there are open handles to an object, it is still valid. It is not destroyed until all handles to the object are closed. When a process terminates for any reason, the OS will auto-close any handles it still had open... – Remy Lebeau Feb 24 '22 at 22:38
  • @WolfgangRoth ... So, lets say Process A creates an event (refcnt=1), then Process B opens the event to wait on it (refcnt=2). If Process A then crashes and exits (refcnt=1), but Process B still has an open handle to the event (refcnt=1), the event is still valid. You can then restart Process A and it can open a new handle to the existing event (refcnt=2) and continue on like nothing happened. – Remy Lebeau Feb 24 '22 at 22:40

1 Answers1

0

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.

Wolfgang Roth
  • 451
  • 4
  • 18