@@ -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 all handles */
609
+ /* Clean up all the 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
0 commit comments