@@ -1931,14 +1931,11 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
19311931#elif  defined(WAIT_USE_WIN32 )
19321932
19331933/* 
1934-  * Wait using Windows' WaitForMultipleObjects(). 
1934+  * Wait using Windows' WaitForMultipleObjects().  Each call only "consumes" one 
1935+  * event, so we keep calling until we've filled up our output buffer to match 
1936+  * the behavior of the other implementations. 
19351937 * 
1936-  * Unfortunately this will only ever return a single readiness notification at 
1937-  * a time.  Note that while the official documentation for 
1938-  * WaitForMultipleObjects is ambiguous about multiple events being "consumed" 
1939-  * with a single bWaitAll = FALSE call, 
1940-  * https://blogs.msdn.microsoft.com/oldnewthing/20150409-00/?p=44273 confirms 
1941-  * that only one event is "consumed". 
1938+  * https://blogs.msdn.microsoft.com/oldnewthing/20150409-00/?p=44273 
19421939 */ 
19431940static  inline  int 
19441941WaitEventSetWaitBlock (WaitEventSet  * set , int  cur_timeout ,
@@ -2023,106 +2020,145 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
20232020	 */ 
20242021	cur_event  =  (WaitEvent  * ) & set -> events [rc  -  WAIT_OBJECT_0  -  1 ];
20252022
2026- 	occurred_events -> pos  =  cur_event -> pos ;
2027- 	occurred_events -> user_data  =  cur_event -> user_data ;
2028- 	occurred_events -> events  =  0 ;
2029- 
2030- 	if  (cur_event -> events  ==  WL_LATCH_SET )
2031- 	{
2032- 		/* 
2033- 		 * We cannot use set->latch->event to reset the fired event if we 
2034- 		 * aren't waiting on this latch now. 
2035- 		 */ 
2036- 		if  (!ResetEvent (set -> handles [cur_event -> pos  +  1 ]))
2037- 			elog (ERROR , "ResetEvent failed: error code %lu" , GetLastError ());
2038- 
2039- 		if  (set -> latch  &&  set -> latch -> is_set )
2040- 		{
2041- 			occurred_events -> fd  =  PGINVALID_SOCKET ;
2042- 			occurred_events -> events  =  WL_LATCH_SET ;
2043- 			occurred_events ++ ;
2044- 			returned_events ++ ;
2045- 		}
2046- 	}
2047- 	else  if  (cur_event -> events  ==  WL_POSTMASTER_DEATH )
2048- 	{
2049- 		/* 
2050- 		 * Postmaster apparently died.  Since the consequences of falsely 
2051- 		 * returning WL_POSTMASTER_DEATH could be pretty unpleasant, we take 
2052- 		 * the trouble to positively verify this with PostmasterIsAlive(), 
2053- 		 * even though there is no known reason to think that the event could 
2054- 		 * be falsely set on Windows. 
2055- 		 */ 
2056- 		if  (!PostmasterIsAliveInternal ())
2057- 		{
2058- 			if  (set -> exit_on_postmaster_death )
2059- 				proc_exit (1 );
2060- 			occurred_events -> fd  =  PGINVALID_SOCKET ;
2061- 			occurred_events -> events  =  WL_POSTMASTER_DEATH ;
2062- 			occurred_events ++ ;
2063- 			returned_events ++ ;
2064- 		}
2065- 	}
2066- 	else  if  (cur_event -> events  &  WL_SOCKET_MASK )
2023+ 	for  (;;)
20672024	{
2068- 		WSANETWORKEVENTS  resEvents ;
2069- 		HANDLE 		handle  =  set -> handles [cur_event -> pos  +  1 ];
2070- 
2071- 		Assert (cur_event -> fd );
2025+ 		int 			next_pos ;
2026+ 		int 			count ;
20722027
2073- 		occurred_events -> fd  =  cur_event -> fd ;
2028+ 		occurred_events -> pos  =  cur_event -> pos ;
2029+ 		occurred_events -> user_data  =  cur_event -> user_data ;
2030+ 		occurred_events -> events  =  0 ;
20742031
2075- 		ZeroMemory (& resEvents , sizeof (resEvents ));
2076- 		if  (WSAEnumNetworkEvents (cur_event -> fd , handle , & resEvents ) !=  0 )
2077- 			elog (ERROR , "failed to enumerate network events: error code %d" ,
2078- 				 WSAGetLastError ());
2079- 		if  ((cur_event -> events  &  WL_SOCKET_READABLE ) && 
2080- 			(resEvents .lNetworkEvents  &  FD_READ ))
2032+ 		if  (cur_event -> events  ==  WL_LATCH_SET )
20812033		{
2082- 			/* data available in socket */ 
2083- 			occurred_events -> events  |= WL_SOCKET_READABLE ;
2084- 
2085- 			/*------ 
2086- 			 * WaitForMultipleObjects doesn't guarantee that a read event will 
2087- 			 * be returned if the latch is set at the same time.  Even if it 
2088- 			 * did, the caller might drop that event expecting it to reoccur 
2089- 			 * on next call.  So, we must force the event to be reset if this 
2090- 			 * WaitEventSet is used again in order to avoid an indefinite 
2091- 			 * hang.  Refer https://msdn.microsoft.com/en-us/library/windows/desktop/ms741576(v=vs.85).aspx 
2092- 			 * for the behavior of socket events. 
2093- 			 *------ 
2034+ 			/* 
2035+ 			 * We cannot use set->latch->event to reset the fired event if we 
2036+ 			 * aren't waiting on this latch now. 
20942037			 */ 
2095- 			cur_event -> reset  =  true;
2096- 		}
2097- 		if  ((cur_event -> events  &  WL_SOCKET_WRITEABLE ) && 
2098- 			(resEvents .lNetworkEvents  &  FD_WRITE ))
2099- 		{
2100- 			/* writeable */ 
2101- 			occurred_events -> events  |= WL_SOCKET_WRITEABLE ;
2102- 		}
2103- 		if  ((cur_event -> events  &  WL_SOCKET_CONNECTED ) && 
2104- 			(resEvents .lNetworkEvents  &  FD_CONNECT ))
2105- 		{
2106- 			/* connected */ 
2107- 			occurred_events -> events  |= WL_SOCKET_CONNECTED ;
2038+ 			if  (!ResetEvent (set -> handles [cur_event -> pos  +  1 ]))
2039+ 				elog (ERROR , "ResetEvent failed: error code %lu" , GetLastError ());
2040+ 
2041+ 			if  (set -> latch  &&  set -> latch -> is_set )
2042+ 			{
2043+ 				occurred_events -> fd  =  PGINVALID_SOCKET ;
2044+ 				occurred_events -> events  =  WL_LATCH_SET ;
2045+ 				occurred_events ++ ;
2046+ 				returned_events ++ ;
2047+ 			}
21082048		}
2109- 		if  ((cur_event -> events  &  WL_SOCKET_ACCEPT ) && 
2110- 			(resEvents .lNetworkEvents  &  FD_ACCEPT ))
2049+ 		else  if  (cur_event -> events  ==  WL_POSTMASTER_DEATH )
21112050		{
2112- 			/* incoming connection could be accepted */ 
2113- 			occurred_events -> events  |= WL_SOCKET_ACCEPT ;
2051+ 			/* 
2052+ 			 * Postmaster apparently died.  Since the consequences of falsely 
2053+ 			 * returning WL_POSTMASTER_DEATH could be pretty unpleasant, we 
2054+ 			 * take the trouble to positively verify this with 
2055+ 			 * PostmasterIsAlive(), even though there is no known reason to 
2056+ 			 * think that the event could be falsely set on Windows. 
2057+ 			 */ 
2058+ 			if  (!PostmasterIsAliveInternal ())
2059+ 			{
2060+ 				if  (set -> exit_on_postmaster_death )
2061+ 					proc_exit (1 );
2062+ 				occurred_events -> fd  =  PGINVALID_SOCKET ;
2063+ 				occurred_events -> events  =  WL_POSTMASTER_DEATH ;
2064+ 				occurred_events ++ ;
2065+ 				returned_events ++ ;
2066+ 			}
21142067		}
2115- 		if  (resEvents . lNetworkEvents  &  FD_CLOSE )
2068+ 		else   if  (cur_event -> events  &  WL_SOCKET_MASK )
21162069		{
2117- 			/* EOF/error, so signal all caller-requested socket flags */ 
2118- 			occurred_events -> events  |= (cur_event -> events  &  WL_SOCKET_MASK );
2119- 		}
2070+ 			WSANETWORKEVENTS  resEvents ;
2071+ 			HANDLE 		handle  =  set -> handles [cur_event -> pos  +  1 ];
21202072
2121- 		if  (occurred_events -> events  !=  0 )
2122- 		{
2123- 			occurred_events ++ ;
2124- 			returned_events ++ ;
2073+ 			Assert (cur_event -> fd );
2074+ 
2075+ 			occurred_events -> fd  =  cur_event -> fd ;
2076+ 
2077+ 			ZeroMemory (& resEvents , sizeof (resEvents ));
2078+ 			if  (WSAEnumNetworkEvents (cur_event -> fd , handle , & resEvents ) !=  0 )
2079+ 				elog (ERROR , "failed to enumerate network events: error code %d" ,
2080+ 					 WSAGetLastError ());
2081+ 			if  ((cur_event -> events  &  WL_SOCKET_READABLE ) && 
2082+ 				(resEvents .lNetworkEvents  &  FD_READ ))
2083+ 			{
2084+ 				/* data available in socket */ 
2085+ 				occurred_events -> events  |= WL_SOCKET_READABLE ;
2086+ 
2087+ 				/*------ 
2088+ 				 * WaitForMultipleObjects doesn't guarantee that a read event 
2089+ 				 * will be returned if the latch is set at the same time.  Even 
2090+ 				 * if it did, the caller might drop that event expecting it to 
2091+ 				 * reoccur on next call.  So, we must force the event to be 
2092+ 				 * reset if this WaitEventSet is used again in order to avoid 
2093+ 				 * an indefinite hang. 
2094+ 				 * 
2095+ 				 * Refer 
2096+ 				 * https://msdn.microsoft.com/en-us/library/windows/desktop/ms741576(v=vs.85).aspx 
2097+ 				 * for the behavior of socket events. 
2098+ 				 *------ 
2099+ 				 */ 
2100+ 				cur_event -> reset  =  true;
2101+ 			}
2102+ 			if  ((cur_event -> events  &  WL_SOCKET_WRITEABLE ) && 
2103+ 				(resEvents .lNetworkEvents  &  FD_WRITE ))
2104+ 			{
2105+ 				/* writeable */ 
2106+ 				occurred_events -> events  |= WL_SOCKET_WRITEABLE ;
2107+ 			}
2108+ 			if  ((cur_event -> events  &  WL_SOCKET_CONNECTED ) && 
2109+ 				(resEvents .lNetworkEvents  &  FD_CONNECT ))
2110+ 			{
2111+ 				/* connected */ 
2112+ 				occurred_events -> events  |= WL_SOCKET_CONNECTED ;
2113+ 			}
2114+ 			if  ((cur_event -> events  &  WL_SOCKET_ACCEPT ) && 
2115+ 				(resEvents .lNetworkEvents  &  FD_ACCEPT ))
2116+ 			{
2117+ 				/* incoming connection could be accepted */ 
2118+ 				occurred_events -> events  |= WL_SOCKET_ACCEPT ;
2119+ 			}
2120+ 			if  (resEvents .lNetworkEvents  &  FD_CLOSE )
2121+ 			{
2122+ 				/* EOF/error, so signal all caller-requested socket flags */ 
2123+ 				occurred_events -> events  |= (cur_event -> events  &  WL_SOCKET_MASK );
2124+ 			}
2125+ 
2126+ 			if  (occurred_events -> events  !=  0 )
2127+ 			{
2128+ 				occurred_events ++ ;
2129+ 				returned_events ++ ;
2130+ 			}
21252131		}
2132+ 
2133+ 		/* Is the output buffer full? */ 
2134+ 		if  (returned_events  ==  nevents )
2135+ 			break ;
2136+ 
2137+ 		/* Have we run out of possible events? */ 
2138+ 		next_pos  =  cur_event -> pos  +  1 ;
2139+ 		if  (next_pos  ==  set -> nevents )
2140+ 			break ;
2141+ 
2142+ 		/* 
2143+ 		 * Poll the rest of the event handles in the array starting at 
2144+ 		 * next_pos being careful to skip over the initial signal handle too. 
2145+ 		 * This time we use a zero timeout. 
2146+ 		 */ 
2147+ 		count  =  set -> nevents  -  next_pos ;
2148+ 		rc  =  WaitForMultipleObjects (count ,
2149+ 									set -> handles  +  1  +  next_pos ,
2150+ 									false,
2151+ 									0 );
2152+ 
2153+ 		/* 
2154+ 		 * We don't distinguish between errors and WAIT_TIMEOUT here because 
2155+ 		 * we already have events to report. 
2156+ 		 */ 
2157+ 		if  (rc  <  WAIT_OBJECT_0  ||  rc  >= WAIT_OBJECT_0  +  count )
2158+ 			break ;
2159+ 
2160+ 		/* We have another event to decode. */ 
2161+ 		cur_event  =  & set -> events [next_pos  +  (rc  -  WAIT_OBJECT_0 )];
21262162	}
21272163
21282164	return  returned_events ;
0 commit comments