mondinmr - 2024-02-02

This library would be very useful for IPC communications.
Using a UDP socket on localhost is unpredictable, as with slightly loaded machines it does not even guarantee packet delivery locally. Using TCP creates a lot of overhead.
Message named pipes would be an excellent solution for Windows RTE.

On Linux, since the release of the extension package, there is no issue, as it is sufficient to develop a component.
However, although now 90% of our clients understand that Linux runtimes are better in every way compared to Windows RTE, especially from the security aspect (Not in kernel space) and the issues with Windows updates, 10% stubbornly insist (sometimes for trivial commercial reasons) on using Windows.
Managing IPC with circular buffers in shared memory is quite ugly, or rather really ugly and unaesthetic.

In the manuals, I saw the SysPipeWindows libraries, so I decided to test them, but unfortunately, I noticed that they are not implemented for RTE devices.
Technically, I could try to open them as regular files, but SysFileOpen returns 16#27 or 16#39 depending on how I set the name (direction of the slashes).

Here is the code to create shared memory and named pipes.
Shared memory work great, named pipes no!

#ifdef Q_OS_WIN32
    SECURITY_ATTRIBUTES sa;
    SECURITY_DESCRIPTOR sd;

    InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
    SetSecurityDescriptorDacl(&sd, TRUE, NULL, FALSE);

    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = &sd;
    sa.bInheritHandle = FALSE;

    const wchar_t* name = L"Global\\ShmTest";
    HANDLE hMapFile = CreateFileMapping(
        INVALID_HANDLE_VALUE,
        NULL,
        PAGE_READWRITE,
        0,
        sizeof(SharedData),
        name);

    if (hMapFile == NULL) {
        qCritical("Error creating shared memory");
        return 1;
    }

    data = static_cast<SharedData*>(MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(SharedData)));
    if (data == NULL) {
        qCritical("Error mapping shared memory");
        return 1;
    }

    HANDLE hPipe = CreateNamedPipe(
        TEXT("\\\\.\\pipe\\MyPipe"),
        PIPE_ACCESS_DUPLEX,
        PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
        PIPE_UNLIMITED_INSTANCES,
        1024 * 1024,
        1024 * 1024,
        NMPWAIT_USE_DEFAULT_WAIT,
        &sa);

    if (hPipe == INVALID_HANDLE_VALUE) {
        qCritical("Error creating named pipe");
        return -1;
    }

    if (!ConnectNamedPipe(hPipe, NULL)) {
        qCritical("Error connecting to named pipe");
        return -1;
    }

    checkPipe(hPipe);
#endif