Fix windows issue with multiple workers

Maxim Dounin mdounin at mdounin.ru
Wed Jun 17 12:29:41 UTC 2015


Hello!

On Wed, Jun 17, 2015 at 09:58:46AM +0200, Sergey Brester wrote:

> Yes, for exactly one child process...

The code in question uses the socket in two process, parent and 
child.

> For example, same (modified for multiprocessing) code does not work on my
> mashine (win7 x64) for 2nd (3th etc.) process (with error 10022 = INVARG). I
> think the handle schould be then duplicated, and see MSDN
> (https://msdn.microsoft.com/en-us/library/windows/desktop/ms724251.aspx)

If something "modified" doesn't work for you - please be exact and 
provide the code which doesn't work.

Below is the version of the code modified to accept connections in 
6 processes simulteniously, and it works fine here.


#include <winsock2.h>
#include <stdio.h>
#include <windows.h>

#pragma comment(lib, "Ws2_32.lib")

int
main(int argc, char *argv[])
{
    int                  rc, i;
    u_long               code;
    SOCKET               listen_socket, s;
    WSADATA              wsaData;
    struct sockaddr_in   sin;
    STARTUPINFO          si;
    PROCESS_INFORMATION  pi;
    char                 command[256];

    rc = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (rc != NO_ERROR) {
        printf("WSAStartup() failed: %d\n", rc);
        return 2;
    }

    if (argc == 2) {
        listen_socket = atoi(argv[1]);
        printf("Inherited socket: %d\n", listen_socket);
        goto accept;
    }
    if (argc != 1) {
        printf("Invalid number of arguments\n");
        return 1;
    }

    listen_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (listen_socket == INVALID_SOCKET) {
        printf("socket failed with error: %ld\n", WSAGetLastError());
        return 1;
    }

    printf("Listen socket: %d\n", listen_socket);

    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = inet_addr("127.0.0.1");
    sin.sin_port = htons(8080);

    if (bind(listen_socket, (SOCKADDR *) &sin, sizeof(sin)) == SOCKET_ERROR) {
        printf("bind() failed: %ld\n", WSAGetLastError());
        return 1;
    }

    if (listen(listen_socket, 1) == SOCKET_ERROR) {
        printf("listen() failed: %ld\n", WSAGetLastError());
        return 1;
    }

    for (i = 0; i < 5; i++) {
        ZeroMemory(&si, sizeof(si));
        si.cb = sizeof(si);
        ZeroMemory(&pi, sizeof(pi));

        _snprintf(command, sizeof(command), "%s %d", argv[0], listen_socket);

        if (CreateProcess(NULL, command,
                          NULL, NULL, 1, 0, NULL, NULL,
                          &si, &pi)
            == 0)
        {
            printf("CreateProcess() failed: %ld\n", GetLastError());
            return 1;
        }

#if 0
        WaitForSingleObject(pi.hProcess, INFINITE);

        if (GetExitCodeProcess(pi.hProcess, &code) == 0) {
            printf("GetExitCodeProcess() failed: %ld\n", GetLastError());
            return 1;
        }

        printf("Child process exited: %d\n", code);
#endif

        CloseHandle(pi.hProcess);
        CloseHandle(pi.hThread);
    }

accept:

    printf("Waiting for client to connect...\n");

    s = accept(listen_socket, NULL, NULL);
    if (s == INVALID_SOCKET) {
        printf("accept() failed: %ld\n", WSAGetLastError());
        return 1;
    }

    printf("Client connected\n");

    return 0;
}

-- 
Maxim Dounin
http://nginx.org/



More information about the nginx-devel mailing list