From bd2ce07dc709354bad7e707e4e6e6bd004db353e 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/4] 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 e61237f..b82ed25 100644
--- a/src/backend/replication/logical/tablesync.c
+++ b/src/backend/replication/logical/tablesync.c
@@ -147,7 +147,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)
@@ -162,14 +167,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)
@@ -180,7 +195,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.8.1

