Fix windows issue with multiple workers

Sergey Brester serg.brester at sebres.de
Wed Jun 17 14:01:17 UTC 2015


Hmm, strange - almost same code, but it does not work... only first 
child can accept connections.

Which version of windows are you using for test?

Am 17.06.2015 14:29, schrieb Maxim Dounin:

> 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 
>> [1])
> 
> 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: %dn", rc);
> return 2;
> }
> 
> if (argc == 2) {
> listen_socket = atoi(argv[1]);
> printf("Inherited socket: %dn", listen_socket);
> goto accept;
> }
> if (argc != 1) {
> printf("Invalid number of argumentsn");
> return 1;
> }
> 
> listen_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
> if (listen_socket == INVALID_SOCKET) {
> printf("socket failed with error: %ldn", WSAGetLastError());
> return 1;
> }
> 
> printf("Listen socket: %dn", 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: %ldn", WSAGetLastError());
> return 1;
> }
> 
> if (listen(listen_socket, 1) == SOCKET_ERROR) {
> printf("listen() failed: %ldn", 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: %ldn", GetLastError());
> return 1;
> }
> 
> #if 0
> WaitForSingleObject(pi.hProcess, INFINITE);
> 
> if (GetExitCodeProcess(pi.hProcess, &code) == 0) {
> printf("GetExitCodeProcess() failed: %ldn", GetLastError());
> return 1;
> }
> 
> printf("Child process exited: %dn", 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: %ldn", WSAGetLastError());
> return 1;
> }
> 
> printf("Client connectedn");
> 
> return 0;
> }


Links:
------
[1] 
https://msdn.microsoft.com/en-us/library/windows/desktop/ms724251.aspx



More information about the nginx-devel mailing list