Commit 9f17ffd8 authored by Tom Lane's avatar Tom Lane

Measure WaitLatch's timeout parameter in milliseconds, not microseconds.

The original definition had the problem that timeouts exceeding about 2100
seconds couldn't be specified on 32-bit machines.  Milliseconds seem like
sufficient resolution, and finer grain than that would be fantasy anyway
on many platforms.

Back-patch to 9.1 so that this aspect of the latch API won't change between
9.1 and later releases.

Peter Geoghegan
parent 4e15a4db
...@@ -10210,7 +10210,9 @@ retry: ...@@ -10210,7 +10210,9 @@ retry:
/* /*
* Wait for more WAL to arrive, or timeout to be reached * Wait for more WAL to arrive, or timeout to be reached
*/ */
WaitLatch(&XLogCtl->recoveryWakeupLatch, WL_LATCH_SET | WL_TIMEOUT, 5000000L); WaitLatch(&XLogCtl->recoveryWakeupLatch,
WL_LATCH_SET | WL_TIMEOUT,
5000L);
ResetLatch(&XLogCtl->recoveryWakeupLatch); ResetLatch(&XLogCtl->recoveryWakeupLatch);
} }
else else
......
...@@ -137,7 +137,7 @@ DisownLatch(volatile Latch *latch) ...@@ -137,7 +137,7 @@ DisownLatch(volatile Latch *latch)
* to wait for. If the latch is already set (and WL_LATCH_SET is given), the * to wait for. If the latch is already set (and WL_LATCH_SET is given), the
* function returns immediately. * function returns immediately.
* *
* The 'timeout' is given in microseconds. It must be >= 0 if WL_TIMEOUT flag * The 'timeout' is given in milliseconds. It must be >= 0 if WL_TIMEOUT flag
* is given. On some platforms, signals cause the timeout to be restarted, * is given. On some platforms, signals cause the timeout to be restarted,
* so beware that the function can sleep for several times longer than the * so beware that the function can sleep for several times longer than the
* specified timeout. * specified timeout.
...@@ -156,6 +156,7 @@ DisownLatch(volatile Latch *latch) ...@@ -156,6 +156,7 @@ DisownLatch(volatile Latch *latch)
* have been satisfied. That should be rare in practice, but the caller * have been satisfied. That should be rare in practice, but the caller
* should not use the return value for anything critical, re-checking the * should not use the return value for anything critical, re-checking the
* situation with PostmasterIsAlive() or read() on a socket as necessary. * situation with PostmasterIsAlive() or read() on a socket as necessary.
* The latch and timeout flag bits can be trusted, however.
*/ */
int int
WaitLatch(volatile Latch *latch, int wakeEvents, long timeout) WaitLatch(volatile Latch *latch, int wakeEvents, long timeout)
...@@ -191,8 +192,8 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock, ...@@ -191,8 +192,8 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
if (wakeEvents & WL_TIMEOUT) if (wakeEvents & WL_TIMEOUT)
{ {
Assert(timeout >= 0); Assert(timeout >= 0);
tv.tv_sec = timeout / 1000000L; tv.tv_sec = timeout / 1000L;
tv.tv_usec = timeout % 1000000L; tv.tv_usec = (timeout % 1000L) * 1000L;
tvp = &tv; tvp = &tv;
} }
......
...@@ -99,7 +99,6 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock, ...@@ -99,7 +99,6 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
int numevents; int numevents;
int result = 0; int result = 0;
int pmdeath_eventno = 0; int pmdeath_eventno = 0;
long timeout_ms;
/* Ignore WL_SOCKET_* events if no valid socket is given */ /* Ignore WL_SOCKET_* events if no valid socket is given */
if (sock == PGINVALID_SOCKET) if (sock == PGINVALID_SOCKET)
...@@ -110,14 +109,11 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock, ...@@ -110,14 +109,11 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
if ((wakeEvents & WL_LATCH_SET) && latch->owner_pid != MyProcPid) if ((wakeEvents & WL_LATCH_SET) && latch->owner_pid != MyProcPid)
elog(ERROR, "cannot wait on a latch owned by another process"); elog(ERROR, "cannot wait on a latch owned by another process");
/* Convert timeout to milliseconds for WaitForMultipleObjects() */ /* Convert timeout to form used by WaitForMultipleObjects() */
if (wakeEvents & WL_TIMEOUT) if (wakeEvents & WL_TIMEOUT)
{
Assert(timeout >= 0); Assert(timeout >= 0);
timeout_ms = timeout / 1000;
}
else else
timeout_ms = INFINITE; timeout = INFINITE;
/* Construct an array of event handles for WaitforMultipleObjects() */ /* Construct an array of event handles for WaitforMultipleObjects() */
latchevent = latch->event; latchevent = latch->event;
...@@ -165,7 +161,7 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock, ...@@ -165,7 +161,7 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
break; break;
} }
rc = WaitForMultipleObjects(numevents, events, FALSE, timeout_ms); rc = WaitForMultipleObjects(numevents, events, FALSE, timeout);
if (rc == WAIT_FAILED) if (rc == WAIT_FAILED)
elog(ERROR, "WaitForMultipleObjects() failed: error code %d", (int) GetLastError()); elog(ERROR, "WaitForMultipleObjects() failed: error code %d", (int) GetLastError());
......
...@@ -407,9 +407,10 @@ pgarch_MainLoop(void) ...@@ -407,9 +407,10 @@ pgarch_MainLoop(void)
if (timeout > 0) if (timeout > 0)
{ {
int rc; int rc;
rc = WaitLatch(&mainloop_latch, rc = WaitLatch(&mainloop_latch,
WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH, WL_LATCH_SET | WL_TIMEOUT | WL_POSTMASTER_DEATH,
timeout * 1000000L); timeout * 1000L);
if (rc & WL_TIMEOUT) if (rc & WL_TIMEOUT)
wakened = true; wakened = true;
} }
......
...@@ -251,7 +251,7 @@ SyncRepWaitForLSN(XLogRecPtr XactCommitLSN) ...@@ -251,7 +251,7 @@ SyncRepWaitForLSN(XLogRecPtr XactCommitLSN)
* cancel/die signal or postmaster death regularly while waiting. Note * cancel/die signal or postmaster death regularly while waiting. Note
* that timeout here does not necessarily release from loop. * that timeout here does not necessarily release from loop.
*/ */
WaitLatch(&MyProc->waitLatch, WL_LATCH_SET | WL_TIMEOUT, 60000000L); WaitLatch(&MyProc->waitLatch, WL_LATCH_SET | WL_TIMEOUT, 60000L);
} }
/* /*
......
...@@ -812,7 +812,7 @@ WalSndLoop(void) ...@@ -812,7 +812,7 @@ WalSndLoop(void)
if (pq_is_send_pending()) if (pq_is_send_pending())
wakeEvents |= WL_SOCKET_WRITEABLE; wakeEvents |= WL_SOCKET_WRITEABLE;
WaitLatchOrSocket(&MyWalSnd->latch, wakeEvents, WaitLatchOrSocket(&MyWalSnd->latch, wakeEvents,
MyProcPort->sock, sleeptime * 1000L); MyProcPort->sock, sleeptime);
/* Check for replication timeout */ /* Check for replication timeout */
if (replication_timeout > 0 && if (replication_timeout > 0 &&
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment