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