diff --git a/src/backend/storage/ipc/latch.c b/src/backend/storage/ipc/latch.c
index b7e5129..052b948 100644
--- a/src/backend/storage/ipc/latch.c
+++ b/src/backend/storage/ipc/latch.c
@@ -643,6 +643,7 @@ AddWaitEventToSet(WaitEventSet *set, uint32 events, pgsocket fd, Latch *latch,
 	event->fd = fd;
 	event->events = events;
 	event->user_data = user_data;
+	event->reset = false;
 
 	if (events == WL_LATCH_SET)
 	{
@@ -689,13 +690,14 @@ ModifyWaitEvent(WaitEventSet *set, int pos, uint32 events, Latch *latch)
 	event = &set->events[pos];
 
 	/*
-	 * If neither the event mask nor the associated latch changes, return
-	 * early. That's an important optimization for some sockets, where
-	 * ModifyWaitEvent is frequently used to switch from waiting for reads to
-	 * waiting on writes.
+	 * If one of the event mask or the associated latch changes or event reset
+	 * is requested, then modify the event, otherwise return early. That's an
+	 * important optimization for some sockets, where ModifyWaitEvent is
+	 * frequently used to switch from waiting for reads to waiting on writes.
 	 */
 	if (events == event->events &&
-		(!(event->events & WL_LATCH_SET) || set->latch == latch))
+		(!(event->events & WL_LATCH_SET) || set->latch == latch) &&
+		!event->reset)
 		return;
 
 	if (event->events & WL_LATCH_SET &&
@@ -727,6 +729,8 @@ ModifyWaitEvent(WaitEventSet *set, int pos, uint32 events, Latch *latch)
 #elif defined(WAIT_USE_WIN32)
 	WaitEventAdjustWin32(set, event);
 #endif
+
+	event->reset = false;
 }
 
 #if defined(WAIT_USE_EPOLL)
@@ -1389,6 +1393,19 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
 	DWORD		rc;
 	WaitEvent  *cur_event;
 
+	/* Reset the wait events */
+	for (cur_event = set->events;
+		 cur_event < (set->events + set->nevents)
+		 && returned_events < nevents;
+		 cur_event++)
+	{
+		if (cur_event->reset)
+		{
+			WaitEventAdjustWin32(set, cur_event);
+			cur_event->reset = false;
+		}
+	}
+
 	/*
 	 * Sleep.
 	 *
@@ -1472,6 +1489,18 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
 		{
 			/* data available in socket */
 			occurred_events->events |= WL_SOCKET_READABLE;
+
+			/*------
+			 * WaitForMultipleObjects doesn't guarantee that a read event will
+			 * be returned if the latch is set at the same time.  Even if it
+			 * did, the caller might drop that event expecting it to reoccur
+			 * on next call.  So, we must force the event to be reset if this
+			 * WaitEventSet is used again in order to avoid an indefinite
+			 * hang.  Refer https://msdn.microsoft.com/en-us/library/windows/desktop/ms741576(v=vs.85).aspx
+			 * for the behavior of socket events.
+			 *------
+			 */
+			cur_event->reset = true;
 		}
 		if ((cur_event->events & WL_SOCKET_WRITEABLE) &&
 			(resEvents.lNetworkEvents & FD_WRITE))
diff --git a/src/include/storage/latch.h b/src/include/storage/latch.h
index e96e88f..c32a873 100644
--- a/src/include/storage/latch.h
+++ b/src/include/storage/latch.h
@@ -133,6 +133,8 @@ typedef struct WaitEvent
 	uint32		events;			/* triggered events */
 	pgsocket	fd;				/* socket fd associated with event */
 	void	   *user_data;		/* pointer provided in AddWaitEventToSet */
+	bool		reset;			/* Is reset of the event required?	As of now
+								 * this is used only for Windows wait event. */
 } WaitEvent;
 
 /* forward declaration to avoid exposing latch.c implementation details */
