Skip to content

Commit 93d7706

Browse files
committed
Fix volatile-safety issue in asyncQueueReadAllNotifications().
The "pos" variable is modified within PG_TRY and then referenced within PG_CATCH, so for strict POSIX conformance it must be marked volatile. Superficially the code looked safe because pos's address was taken, which was sufficient to force it into memory ... but it's not sufficient to ensure that the compiler applies updates exactly where the program text says to. The volatility marking has to extend into a couple of subroutines too, but I think that's probably a good thing because the risk of out-of-order updates is mostly in those subroutines not asyncQueueReadAllNotifications() itself. In principle the compiler could have re-ordered operations such that an error could be thrown while "pos" had an incorrect value. It's unclear how real the risk is here, but for safety back-patch to all active branches.
1 parent 3a3ee65 commit 93d7706

File tree

1 file changed

+5
-5
lines changed

1 file changed

+5
-5
lines changed

src/backend/commands/async.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -371,13 +371,13 @@ static void Exec_UnlistenAllCommit(void);
371371
static bool IsListeningOn(const char *channel);
372372
static void asyncQueueUnregister(void);
373373
static bool asyncQueueIsFull(void);
374-
static bool asyncQueueAdvance(QueuePosition *position, int entryLength);
374+
static bool asyncQueueAdvance(volatile QueuePosition *position, int entryLength);
375375
static void asyncQueueNotificationToEntry(Notification *n, AsyncQueueEntry *qe);
376376
static ListCell *asyncQueueAddEntries(ListCell *nextNotify);
377377
static void asyncQueueFillWarning(void);
378378
static bool SignalBackends(void);
379379
static void asyncQueueReadAllNotifications(void);
380-
static bool asyncQueueProcessPageEntries(QueuePosition *current,
380+
static bool asyncQueueProcessPageEntries(volatile QueuePosition *current,
381381
QueuePosition stop,
382382
char *page_buffer);
383383
static void asyncQueueAdvanceTail(void);
@@ -1225,7 +1225,7 @@ asyncQueueIsFull(void)
12251225
* returns true, else false.
12261226
*/
12271227
static bool
1228-
asyncQueueAdvance(QueuePosition *position, int entryLength)
1228+
asyncQueueAdvance(volatile QueuePosition *position, int entryLength)
12291229
{
12301230
int pageno = QUEUE_POS_PAGE(*position);
12311231
int offset = QUEUE_POS_OFFSET(*position);
@@ -1815,7 +1815,7 @@ DisableNotifyInterrupt(void)
18151815
static void
18161816
asyncQueueReadAllNotifications(void)
18171817
{
1818-
QueuePosition pos;
1818+
volatile QueuePosition pos;
18191819
QueuePosition oldpos;
18201820
QueuePosition head;
18211821
bool advanceTail;
@@ -1975,7 +1975,7 @@ asyncQueueReadAllNotifications(void)
19751975
* The QueuePosition *current is advanced past all processed messages.
19761976
*/
19771977
static bool
1978-
asyncQueueProcessPageEntries(QueuePosition *current,
1978+
asyncQueueProcessPageEntries(volatile QueuePosition *current,
19791979
QueuePosition stop,
19801980
char *page_buffer)
19811981
{

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy