@@ -1931,14 +1931,11 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
1931
1931
#elif defined(WAIT_USE_WIN32 )
1932
1932
1933
1933
/*
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.
1935
1937
*
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
1942
1939
*/
1943
1940
static inline int
1944
1941
WaitEventSetWaitBlock (WaitEventSet * set , int cur_timeout ,
@@ -2023,106 +2020,145 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
2023
2020
*/
2024
2021
cur_event = (WaitEvent * ) & set -> events [rc - WAIT_OBJECT_0 - 1 ];
2025
2022
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 (;;)
2067
2024
{
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 ;
2072
2027
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 ;
2074
2031
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 )
2081
2033
{
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.
2094
2037
*/
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
+ }
2108
2048
}
2109
- if ((cur_event -> events & WL_SOCKET_ACCEPT ) &&
2110
- (resEvents .lNetworkEvents & FD_ACCEPT ))
2049
+ else if (cur_event -> events == WL_POSTMASTER_DEATH )
2111
2050
{
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
+ }
2114
2067
}
2115
- if (resEvents . lNetworkEvents & FD_CLOSE )
2068
+ else if (cur_event -> events & WL_SOCKET_MASK )
2116
2069
{
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 ];
2120
2072
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
+ }
2125
2131
}
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 )];
2126
2162
}
2127
2163
2128
2164
return returned_events ;
0 commit comments