diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 1664fcee2a..f9070da574 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -1728,6 +1728,33 @@ ServerLoop(void)
 
 	nSockets = initMasks(&readmask);
 
+	/*
+	 * Issue a dummy select() call before we unblock signals.  The point of
+	 * this is that select() may be reached via a PLT indirection, and that
+	 * indirection will need to be resolved on first use, and on some
+	 * platforms the dynamic loader's resolution code takes a lock.  If that
+	 * lock is taken while signals are unblocked then we risk self-deadlock
+	 * should a signal handler do anything that also needs the loader lock.
+	 * This is a low-probability failure, since it can only happen if a signal
+	 * arrives with just the right timing during the first pass through the
+	 * server loop.  However, it has been seen repeatedly on slow single-CPU
+	 * machines.
+	 *
+	 * Likewise, issue a dummy pg_usleep() to ensure we've resolved any PLT
+	 * indirections needed in the PM_WAIT_DEAD_END path.  (The PG_SETMASK
+	 * calls could also be at hazard, had we not issued one of those when
+	 * blocking signals to begin with.)
+	 */
+	{
+		struct timeval timeout0;
+
+		timeout0.tv_sec = 0;
+		timeout0.tv_usec = 0;
+		(void) select(0, NULL, NULL, NULL, &timeout0);
+		pg_usleep(0);
+	}
+
+	/* Main server loop begins here */
 	for (;;)
 	{
 		fd_set		rmask;
@@ -1750,6 +1777,7 @@ ServerLoop(void)
 		{
 			PG_SETMASK(&UnBlockSig);
 
+			/* Add nothing else in this unblocked-signals section */
 			pg_usleep(100000L); /* 100 msec seems reasonable */
 			selres = 0;
 
@@ -1765,6 +1793,7 @@ ServerLoop(void)
 
 			PG_SETMASK(&UnBlockSig);
 
+			/* Add nothing else in this unblocked-signals section */
 			selres = select(nSockets, &rmask, NULL, NULL, &timeout);
 
 			PG_SETMASK(&BlockSig);
