@@ -137,6 +137,7 @@ pgwin32_waitforsinglesocket(SOCKET s, int what, int timeout)
137
137
HANDLE events [2 ];
138
138
int r ;
139
139
140
+ /* Create an event object just once and use it on all future calls */
140
141
if (waitevent == INVALID_HANDLE_VALUE )
141
142
{
142
143
waitevent = CreateEvent (NULL , TRUE, FALSE,NULL );
@@ -150,20 +151,19 @@ pgwin32_waitforsinglesocket(SOCKET s, int what, int timeout)
150
151
(errmsg_internal ("could not reset socket waiting event: %i" , (int )GetLastError ())));
151
152
152
153
/*
153
- * make sure we don't multiplex this kernel event object with a different
154
- * socket from a previous call
154
+ * Track whether socket is UDP or not. (NB: most likely, this is both
155
+ * useless and wrong; there is no reason to think that the behavior of
156
+ * WSAEventSelect is different for TCP and UDP.)
155
157
*/
156
-
157
158
if (current_socket != s )
158
- {
159
- if (current_socket != -1 )
160
- WSAEventSelect (current_socket ,waitevent ,0 );
161
159
isUDP = isDataGram (s );
162
- }
163
-
164
160
current_socket = s ;
165
161
166
- if (WSAEventSelect (s ,waitevent ,what )== SOCKET_ERROR )
162
+ /*
163
+ * Attach event to socket. NOTE: we must detach it again before returning,
164
+ * since other bits of code may try to attach other events to the socket.
165
+ */
166
+ if (WSAEventSelect (s ,waitevent ,what )!= 0 )
167
167
{
168
168
TranslateSocketError ();
169
169
return 0 ;
@@ -196,10 +196,14 @@ pgwin32_waitforsinglesocket(SOCKET s, int what, int timeout)
196
196
197
197
r = WSASend (s ,& buf ,1 ,& sent ,0 ,NULL ,NULL );
198
198
if (r == 0 )/* Completed - means things are fine! */
199
+ {
200
+ WSAEventSelect (s ,NULL ,0 );
199
201
return 1 ;
202
+ }
200
203
else if (WSAGetLastError ()!= WSAEWOULDBLOCK )
201
204
{
202
205
TranslateSocketError ();
206
+ WSAEventSelect (s ,NULL ,0 );
203
207
return 0 ;
204
208
}
205
209
}
@@ -210,6 +214,8 @@ pgwin32_waitforsinglesocket(SOCKET s, int what, int timeout)
210
214
else
211
215
r = WaitForMultipleObjectsEx (2 ,events , FALSE,timeout , TRUE);
212
216
217
+ WSAEventSelect (s ,NULL ,0 );
218
+
213
219
if (r == WAIT_OBJECT_0 || r == WAIT_IO_COMPLETION )
214
220
{
215
221
pgwin32_dispatch_queued_signals ();
@@ -219,7 +225,10 @@ pgwin32_waitforsinglesocket(SOCKET s, int what, int timeout)
219
225
if (r == WAIT_OBJECT_0 + 1 )
220
226
return 1 ;
221
227
if (r == WAIT_TIMEOUT )
228
+ {
229
+ errno = EWOULDBLOCK ;
222
230
return 0 ;
231
+ }
223
232
ereport (ERROR ,
224
233
(errmsg_internal ("unrecognized return value from WaitForMultipleObjects: %i (%i)" ,r , (int )GetLastError ())));
225
234
return 0 ;
@@ -543,9 +552,12 @@ pgwin32_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, c
543
552
if (writefds && FD_ISSET (sockets [i ],writefds ))
544
553
flags |=FD_WRITE |FD_CLOSE ;
545
554
546
- if (WSAEventSelect (sockets [i ],events [i ],flags )== SOCKET_ERROR )
555
+ if (WSAEventSelect (sockets [i ],events [i ],flags )!= 0 )
547
556
{
548
557
TranslateSocketError ();
558
+ /* release already-assigned event objects */
559
+ while (-- i >=0 )
560
+ WSAEventSelect (sockets [i ],NULL ,0 );
549
561
for (i = 0 ;i < numevents ;i ++ )
550
562
WSACloseEvent (events [i ]);
551
563
return -1 ;
@@ -565,9 +577,9 @@ pgwin32_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, c
565
577
for (i = 0 ;i < numevents ;i ++ )
566
578
{
567
579
ZeroMemory (& resEvents ,sizeof (resEvents ));
568
- if (WSAEnumNetworkEvents (sockets [i ],events [i ],& resEvents )== SOCKET_ERROR )
580
+ if (WSAEnumNetworkEvents (sockets [i ],events [i ],& resEvents )!= 0 )
569
581
ereport (FATAL ,
570
- (errmsg_internal ("failed to enumerate network events: %i" , (int )GetLastError ())));
582
+ (errmsg_internal ("failed to enumerate network events: %i" , (int )WSAGetLastError ())));
571
583
/* Read activity? */
572
584
if (readfds && FD_ISSET (sockets [i ],readfds ))
573
585
{
@@ -594,10 +606,10 @@ pgwin32_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, c
594
606
}
595
607
}
596
608
597
- /* Clean up allhandles */
609
+ /* Clean up allthe event objects */
598
610
for (i = 0 ;i < numevents ;i ++ )
599
611
{
600
- WSAEventSelect (sockets [i ],events [ i ] ,0 );
612
+ WSAEventSelect (sockets [i ],NULL ,0 );
601
613
WSACloseEvent (events [i ]);
602
614
}
603
615