1
/*-------------------------------------------------------------------------
4
* Microsoft Windows Win32 Socket Functions
6
* Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
9
* src/backend/port/win32/socket.c
11
*-------------------------------------------------------------------------
17
* Indicate if pgwin32_recv() and pgwin32_send() should operate
18
* in non-blocking mode.
20
* Since the socket emulation layer always sets the actual socket to
21
* non-blocking mode in order to be able to deliver signals, we must
22
* specify this in a separate flag if we actually need non-blocking
25
* This flag changes the behaviour *globally* for all socket operations,
26
* so it should only be set for very short periods of time.
28
int pgwin32_noblock = 0;
38
* Blocking socket functions implemented so they listen on both
39
* the socket and the signal event, required for signal handling.
43
* Convert the last socket error code into errno
46
TranslateSocketError(void)
48
switch (WSAGetLastError())
50
case WSANOTINITIALISED:
54
case WSAESOCKTNOSUPPORT:
56
case WSAEINVALIDPROVIDER:
57
case WSAEINVALIDPROCTABLE:
70
case WSAEPROTONOSUPPORT:
72
errno = EPROTONOSUPPORT;
98
errno = ECONNREFUSED; /* ENOTCONN? */
102
(errmsg_internal("Unknown win32 socket error code: %i", WSAGetLastError())));
108
pgwin32_poll_signals(void)
110
if (UNBLOCKED_SIGNAL_QUEUE())
112
pgwin32_dispatch_queued_signals();
123
int typelen = sizeof(type);
125
if (getsockopt(s, SOL_SOCKET, SO_TYPE, (char *) &type, &typelen))
128
return (type == SOCK_DGRAM) ? 1 : 0;
132
pgwin32_waitforsinglesocket(SOCKET s, int what, int timeout)
134
static HANDLE waitevent = INVALID_HANDLE_VALUE;
135
static SOCKET current_socket = -1;
136
static int isUDP = 0;
140
if (waitevent == INVALID_HANDLE_VALUE)
142
waitevent = CreateEvent(NULL, TRUE, FALSE, NULL);
144
if (waitevent == INVALID_HANDLE_VALUE)
146
(errmsg_internal("Failed to create socket waiting event: %i", (int) GetLastError())));
148
else if (!ResetEvent(waitevent))
150
(errmsg_internal("Failed to reset socket waiting event: %i", (int) GetLastError())));
153
* make sure we don't multiplex this kernel event object with a different
154
* socket from a previous call
157
if (current_socket != s)
159
if (current_socket != -1)
160
WSAEventSelect(current_socket, waitevent, 0);
161
isUDP = isDataGram(s);
166
if (WSAEventSelect(s, waitevent, what) == SOCKET_ERROR)
168
TranslateSocketError();
172
events[0] = pgwin32_signal_event;
173
events[1] = waitevent;
176
* Just a workaround of unknown locking problem with writing in UDP socket
177
* under high load: Client's pgsql backend sleeps infinitely in
178
* WaitForMultipleObjectsEx, pgstat process sleeps in pgwin32_select().
179
* So, we will wait with small timeout(0.1 sec) and if sockect is still
180
* blocked, try WSASend (see comments in pgwin32_select) and wait again.
182
if ((what & FD_WRITE) && isUDP)
186
r = WaitForMultipleObjectsEx(2, events, FALSE, 100, TRUE);
188
if (r == WAIT_TIMEOUT)
197
r = WSASend(s, &buf, 1, &sent, 0, NULL, NULL);
198
if (r == 0) /* Completed - means things are fine! */
200
else if (WSAGetLastError() != WSAEWOULDBLOCK)
202
TranslateSocketError();
211
r = WaitForMultipleObjectsEx(2, events, FALSE, timeout, TRUE);
213
if (r == WAIT_OBJECT_0 || r == WAIT_IO_COMPLETION)
215
pgwin32_dispatch_queued_signals();
219
if (r == WAIT_OBJECT_0 + 1)
221
if (r == WAIT_TIMEOUT)
224
(errmsg_internal("Bad return from WaitForMultipleObjects: %i (%i)", r, (int) GetLastError())));
229
* Create a socket, setting it to overlapped and non-blocking
232
pgwin32_socket(int af, int type, int protocol)
235
unsigned long on = 1;
237
s = WSASocket(af, type, protocol, NULL, 0, WSA_FLAG_OVERLAPPED);
238
if (s == INVALID_SOCKET)
240
TranslateSocketError();
241
return INVALID_SOCKET;
244
if (ioctlsocket(s, FIONBIO, &on))
246
TranslateSocketError();
247
return INVALID_SOCKET;
256
pgwin32_accept(SOCKET s, struct sockaddr * addr, int *addrlen)
261
* Poll for signals, but don't return with EINTR, since we don't handle
264
pgwin32_poll_signals();
266
rs = WSAAccept(s, addr, addrlen, NULL, 0);
267
if (rs == INVALID_SOCKET)
269
TranslateSocketError();
270
return INVALID_SOCKET;
276
/* No signal delivery during connect. */
278
pgwin32_connect(SOCKET s, const struct sockaddr * addr, int addrlen)
282
r = WSAConnect(s, addr, addrlen, NULL, NULL, NULL, NULL);
286
if (WSAGetLastError() != WSAEWOULDBLOCK)
288
TranslateSocketError();
292
while (pgwin32_waitforsinglesocket(s, FD_CONNECT, INFINITE) == 0)
294
/* Loop endlessly as long as we are just delivering signals */
301
pgwin32_recv(SOCKET s, char *buf, int len, int f)
309
if (pgwin32_poll_signals())
315
r = WSARecv(s, &wbuf, 1, &b, &flags, NULL, NULL);
316
if (r != SOCKET_ERROR && b > 0)
317
/* Read succeeded right away */
320
if (r == SOCKET_ERROR &&
321
WSAGetLastError() != WSAEWOULDBLOCK)
323
TranslateSocketError();
330
* No data received, and we are in "emulated non-blocking mode", so
331
* return indicating that we'd block if we were to continue.
337
/* No error, zero bytes (win2000+) or error+WSAEWOULDBLOCK (<=nt4) */
339
for (n = 0; n < 5; n++)
341
if (pgwin32_waitforsinglesocket(s, FD_READ | FD_CLOSE | FD_ACCEPT,
343
return -1; /* errno already set */
345
r = WSARecv(s, &wbuf, 1, &b, &flags, NULL, NULL);
346
if (r == SOCKET_ERROR)
348
if (WSAGetLastError() == WSAEWOULDBLOCK)
351
* There seem to be cases on win2k (at least) where WSARecv
352
* can return WSAEWOULDBLOCK even when
353
* pgwin32_waitforsinglesocket claims the socket is readable.
354
* In this case, just sleep for a moment and try again. We try
355
* up to 5 times - if it fails more than that it's not likely
361
TranslateSocketError();
367
(errmsg_internal("Failed to read from ready socket (after retries)")));
373
* The second argument to send() is defined by SUS to be a "const void *"
374
* and so we use the same signature here to keep compilers happy when
377
* But the buf member of a WSABUF struct is defined as "char *", so we cast
378
* the second argument to that here when assigning it, also to keep compilers
383
pgwin32_send(SOCKET s, const void *buf, int len, int flags)
389
if (pgwin32_poll_signals())
393
wbuf.buf = (char *) buf;
396
* Readiness of socket to send data to UDP socket may be not true: socket
397
* can become busy again! So loop until send or error occurs.
401
r = WSASend(s, &wbuf, 1, &b, flags, NULL, NULL);
402
if (r != SOCKET_ERROR && b > 0)
403
/* Write succeeded right away */
406
if (r == SOCKET_ERROR &&
407
WSAGetLastError() != WSAEWOULDBLOCK)
409
TranslateSocketError();
416
* No data sent, and we are in "emulated non-blocking mode", so
417
* return indicating that we'd block if we were to continue.
423
/* No error, zero bytes (win2000+) or error+WSAEWOULDBLOCK (<=nt4) */
425
if (pgwin32_waitforsinglesocket(s, FD_WRITE | FD_CLOSE, INFINITE) == 0)
434
* Wait for activity on one or more sockets.
435
* While waiting, allow signals to run
437
* NOTE! Currently does not implement exceptfds check,
438
* since it is not used in postgresql!
441
pgwin32_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timeval * timeout)
443
WSAEVENT events[FD_SETSIZE * 2]; /* worst case is readfds totally
444
* different from writefds, so
445
* 2*FD_SETSIZE sockets */
446
SOCKET sockets[FD_SETSIZE * 2];
450
DWORD timeoutval = WSA_INFINITE;
455
Assert(exceptfds == NULL);
457
if (pgwin32_poll_signals())
460
FD_ZERO(&outreadfds);
461
FD_ZERO(&outwritefds);
464
* Write FDs are different in the way that it is only flagged by
465
* WSASelectEvent() if we have tried to write to them first. So try an
470
for (i = 0; i < writefds->fd_count; i++)
479
r = WSASend(writefds->fd_array[i], &buf, 1, &sent, 0, NULL, NULL);
480
if (r == 0) /* Completed - means things are fine! */
481
FD_SET(writefds->fd_array[i], &outwritefds);
484
{ /* Not completed */
485
if (WSAGetLastError() != WSAEWOULDBLOCK)
488
* Not completed, and not just "would block", so an error
491
FD_SET(writefds->fd_array[i], &outwritefds);
494
if (outwritefds.fd_count > 0)
496
memcpy(writefds, &outwritefds, sizeof(fd_set));
499
return outwritefds.fd_count;
504
/* Now set up for an actual select */
508
/* timeoutval is in milliseconds */
509
timeoutval = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
514
for (i = 0; i < readfds->fd_count; i++)
516
events[numevents] = WSACreateEvent();
517
sockets[numevents] = readfds->fd_array[i];
521
if (writefds != NULL)
523
for (i = 0; i < writefds->fd_count; i++)
526
!FD_ISSET(writefds->fd_array[i], readfds))
528
/* If the socket is not in the read list */
529
events[numevents] = WSACreateEvent();
530
sockets[numevents] = writefds->fd_array[i];
536
for (i = 0; i < numevents; i++)
540
if (readfds && FD_ISSET(sockets[i], readfds))
541
flags |= FD_READ | FD_ACCEPT | FD_CLOSE;
543
if (writefds && FD_ISSET(sockets[i], writefds))
544
flags |= FD_WRITE | FD_CLOSE;
546
if (WSAEventSelect(sockets[i], events[i], flags) == SOCKET_ERROR)
548
TranslateSocketError();
549
for (i = 0; i < numevents; i++)
550
WSACloseEvent(events[i]);
555
events[numevents] = pgwin32_signal_event;
556
r = WaitForMultipleObjectsEx(numevents + 1, events, FALSE, timeoutval, TRUE);
557
if (r != WAIT_TIMEOUT && r != WAIT_IO_COMPLETION && r != (WAIT_OBJECT_0 + numevents))
560
* We scan all events, even those not signalled, in case more than one
561
* event has been tagged but Wait.. can only return one.
563
WSANETWORKEVENTS resEvents;
565
for (i = 0; i < numevents; i++)
567
ZeroMemory(&resEvents, sizeof(resEvents));
568
if (WSAEnumNetworkEvents(sockets[i], events[i], &resEvents) == SOCKET_ERROR)
570
(errmsg_internal("failed to enumerate network events: %i", (int) GetLastError())));
572
if (readfds && FD_ISSET(sockets[i], readfds))
574
if ((resEvents.lNetworkEvents & FD_READ) ||
575
(resEvents.lNetworkEvents & FD_ACCEPT) ||
576
(resEvents.lNetworkEvents & FD_CLOSE))
578
FD_SET(sockets[i], &outreadfds);
583
/* Write activity? */
584
if (writefds && FD_ISSET(sockets[i], writefds))
586
if ((resEvents.lNetworkEvents & FD_WRITE) ||
587
(resEvents.lNetworkEvents & FD_CLOSE))
589
FD_SET(sockets[i], &outwritefds);
597
/* Clean up all handles */
598
for (i = 0; i < numevents; i++)
600
WSAEventSelect(sockets[i], events[i], 0);
601
WSACloseEvent(events[i]);
604
if (r == WSA_WAIT_TIMEOUT)
613
if (r == WAIT_OBJECT_0 + numevents)
615
pgwin32_dispatch_queued_signals();
624
/* Overwrite socket sets with our resulting values */
626
memcpy(readfds, &outreadfds, sizeof(fd_set));
628
memcpy(writefds, &outwritefds, sizeof(fd_set));
634
* Return win32 error string, since strerror can't
635
* handle winsock codes
637
static char wserrbuf[256];
639
pgwin32_socket_strerror(int err)
641
static HANDLE handleDLL = INVALID_HANDLE_VALUE;
643
if (handleDLL == INVALID_HANDLE_VALUE)
645
handleDLL = LoadLibraryEx("netmsg.dll", NULL, DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE);
646
if (handleDLL == NULL)
648
(errmsg_internal("Failed to load netmsg.dll: %i", (int) GetLastError())));
651
ZeroMemory(&wserrbuf, sizeof(wserrbuf));
652
if (FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_FROM_HMODULE,
655
MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
657
sizeof(wserrbuf) - 1,
660
/* Failed to get id */
661
sprintf(wserrbuf, "Unknown winsock error %i", err);