diff --git a/src/backend/commands/vacuumlazy.c b/src/backend/commands/vacuumlazy.c
index 231e92d..56b2f1a 100644
--- a/src/backend/commands/vacuumlazy.c
+++ b/src/backend/commands/vacuumlazy.c
@@ -1700,7 +1700,6 @@ lazy_truncate_heap(Relation onerel, LVRelStats *vacrelstats)
 	BlockNumber old_rel_pages = vacrelstats->rel_pages;
 	BlockNumber new_rel_pages;
 	PGRUsage	ru0;
-	int			lock_retry;
 
 	pg_rusage_init(&ru0);
 
@@ -1721,33 +1720,19 @@ lazy_truncate_heap(Relation onerel, LVRelStats *vacrelstats)
 		 * lock).
 		 */
 		vacrelstats->lock_waiter_detected = false;
-		lock_retry = 0;
-		while (true)
+		if (!PatientLockRelation(onerel, AccessExclusiveLock,
+								VACUUM_TRUNCATE_LOCK_TIMEOUT,
+								VACUUM_TRUNCATE_LOCK_WAIT_INTERVAL))
 		{
-			if (ConditionalLockRelation(onerel, AccessExclusiveLock))
-				break;
-
 			/*
-			 * Check for interrupts while trying to (re-)acquire the exclusive
-			 * lock.
+			 * We failed to establish the lock in the specified number of
+			 * retries. This means we give up truncating.
 			 */
-			CHECK_FOR_INTERRUPTS();
-
-			if (++lock_retry > (VACUUM_TRUNCATE_LOCK_TIMEOUT /
-								VACUUM_TRUNCATE_LOCK_WAIT_INTERVAL))
-			{
-				/*
-				 * We failed to establish the lock in the specified number of
-				 * retries. This means we give up truncating.
-				 */
-				vacrelstats->lock_waiter_detected = true;
-				ereport(elevel,
-						(errmsg("\"%s\": stopping truncate due to conflicting lock request",
-								RelationGetRelationName(onerel))));
-				return;
-			}
-
-			pg_usleep(VACUUM_TRUNCATE_LOCK_WAIT_INTERVAL);
+			vacrelstats->lock_waiter_detected = true;
+			ereport(elevel,
+					(errmsg("\"%s\": stopping truncate due to conflicting lock request",
+							RelationGetRelationName(onerel))));
+			return;
 		}
 
 		/*
diff --git a/src/backend/storage/lmgr/lmgr.c b/src/backend/storage/lmgr/lmgr.c
index cbee20e..63caf36 100644
--- a/src/backend/storage/lmgr/lmgr.c
+++ b/src/backend/storage/lmgr/lmgr.c
@@ -248,6 +248,62 @@ ConditionalLockRelation(Relation relation, LOCKMODE lockmode)
 }
 
 /*
+ *		PatientLockRelation
+ *
+ * This is a convenience routine for acquiring a lock while allowing other
+ * locks to pass by. "Patient" might also be taken to mean "low priority".
+ */
+bool
+PatientLockRelation(Relation relation, LOCKMODE lockmode,
+					long lock_timeout, long lock_wait_interval)
+{
+	LOCKTAG		tag;
+	LockAcquireResult res;
+	int			lock_retry = 0;
+	int			num_attempts;
+
+	if (lock_wait_interval <= 0)
+		elog(ERROR, "invalid lock wait interval");
+
+	if (lock_timeout < 0)
+		elog(ERROR, "invalid lock timeout");
+
+	num_attempts = (int) lock_timeout / lock_wait_interval;
+	if (num_attempts < 1)
+		num_attempts = 1;
+
+	SET_LOCKTAG_RELATION(tag,
+						 relation->rd_lockInfo.lockRelId.dbId,
+						 relation->rd_lockInfo.lockRelId.relId);
+
+	while (lock_retry++ < num_attempts)
+	{
+		res = LockAcquire(&tag, lockmode, false, true);
+
+		if (res != LOCKACQUIRE_NOT_AVAIL)
+		{
+			/*
+			 * Now that we have the lock, check for invalidation messages; see notes
+			 * in LockRelationOid.
+			 */
+			if (res != LOCKACQUIRE_ALREADY_HELD)
+				AcceptInvalidationMessages();
+
+			return true;
+		}
+
+		/*
+		 * Check for interrupts while trying to (re-)acquire the lock.
+		 */
+		CHECK_FOR_INTERRUPTS();
+
+		pg_usleep(lock_wait_interval);
+	}
+
+	return false;
+}
+
+/*
  *		UnlockRelation
  *
  * This is a convenience routine for unlocking a relation without also
diff --git a/src/include/storage/lmgr.h b/src/include/storage/lmgr.h
index 8288e7d..4b66c10 100644
--- a/src/include/storage/lmgr.h
+++ b/src/include/storage/lmgr.h
@@ -44,6 +44,8 @@ extern void UnlockRelationOid(Oid relid, LOCKMODE lockmode);
 
 extern void LockRelation(Relation relation, LOCKMODE lockmode);
 extern bool ConditionalLockRelation(Relation relation, LOCKMODE lockmode);
+extern bool PatientLockRelation(Relation relation, LOCKMODE lockmode,
+								long lock_timeout, long lock_wait_interval);
 extern void UnlockRelation(Relation relation, LOCKMODE lockmode);
 extern bool LockHasWaitersRelation(Relation relation, LOCKMODE lockmode);
 
