>From e0a7a2a8ae3479cad609ea4a60fca49910fe0ed0 Mon Sep 17 00:00:00 2001
From: Petr Jelinek <pjmodos@pjmodos.net>
Date: Wed, 24 May 2017 20:37:12 +0200
Subject: [PATCH 2/3] Make tablesync worker exit when apply dies while it was
 waiting for it

---
 src/backend/replication/logical/tablesync.c | 21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/src/backend/replication/logical/tablesync.c b/src/backend/replication/logical/tablesync.c
index b92cc85..fe94d45 100644
--- a/src/backend/replication/logical/tablesync.c
+++ b/src/backend/replication/logical/tablesync.c
@@ -144,7 +144,12 @@ finish_sync_worker(void)
 /*
  * Wait until the table synchronization change.
  *
- * Returns false if the relation subscription state disappeared.
+ * If called from apply worker, it will wait for the synchronization worker
+ * to change table state in shmem, and when called from synchronization
+ * worker it will wait for apply worker to change table state in shmem.
+ *
+ * Returns false if the opposite worker has disappeared or table state has
+ * been reset.
  */
 static bool
 wait_for_sync_status_change(Oid relid, char origstate)
@@ -159,14 +164,24 @@ wait_for_sync_status_change(Oid relid, char origstate)
 		CHECK_FOR_INTERRUPTS();
 
 		LWLockAcquire(LogicalRepWorkerLock, LW_SHARED);
+
+		/* Check if the opposite worker is still running and bail if not. */
 		worker = logicalrep_worker_find(MyLogicalRepWorker->subid,
-										relid, false);
+									  IsTablesyncWorker() ? InvalidOid : relid,
+										false);
 		if (!worker)
 		{
 			LWLockRelease(LogicalRepWorkerLock);
 			return false;
 		}
+
+		/* From now on worker is expected to be synchronization worker. */
+		if (IsTablesyncWorker())
+			worker = MyLogicalRepWorker;
+
+		Assert(worker->relid == relid);
 		state = worker->relstate;
+
 		LWLockRelease(LogicalRepWorkerLock);
 
 		if (state == SUBREL_STATE_UNKNOWN)
@@ -177,7 +192,7 @@ wait_for_sync_status_change(Oid relid, char origstate)
 
 		rc = WaitLatch(&MyProc->procLatch,
 					   WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
-					   10000L, WAIT_EVENT_LOGICAL_SYNC_STATE_CHANGE);
+					   1000L, WAIT_EVENT_LOGICAL_SYNC_STATE_CHANGE);
 
 		/* emergency bailout if postmaster has died */
 		if (rc & WL_POSTMASTER_DEATH)
-- 
2.7.4

