aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/async.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/async.c')
-rw-r--r--src/backend/commands/async.c213
1 files changed, 100 insertions, 113 deletions
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index da133788960..69d97d09237 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/async.c,v 1.125 2005/10/06 21:30:32 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/async.c,v 1.126 2005/10/15 02:49:15 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -106,8 +106,7 @@
*/
static List *pendingNotifies = NIL;
-static List *upperPendingNotifies = NIL; /* list of upper-xact
- * lists */
+static List *upperPendingNotifies = NIL; /* list of upper-xact lists */
/*
* State for inbound notifies consists of two flags: one saying whether
@@ -158,8 +157,8 @@ Async_Notify(const char *relname)
if (!AsyncExistsPendingNotify(relname))
{
/*
- * The name list needs to live until end of transaction, so store
- * it in the transaction context.
+ * The name list needs to live until end of transaction, so store it
+ * in the transaction context.
*/
MemoryContext oldcontext;
@@ -208,7 +207,7 @@ Async_Listen(const char *relname)
Form_pg_listener listener = (Form_pg_listener) GETSTRUCT(tuple);
if (listener->listenerpid == MyProcPid &&
- strncmp(NameStr(listener->relname), relname, NAMEDATALEN) == 0)
+ strncmp(NameStr(listener->relname), relname, NAMEDATALEN) == 0)
{
alreadyListener = true;
/* No need to scan the rest of the table */
@@ -298,14 +297,14 @@ Async_Unlisten(const char *relname)
Form_pg_listener listener = (Form_pg_listener) GETSTRUCT(tuple);
if (listener->listenerpid == MyProcPid &&
- strncmp(NameStr(listener->relname), relname, NAMEDATALEN) == 0)
+ strncmp(NameStr(listener->relname), relname, NAMEDATALEN) == 0)
{
/* Found the matching tuple, delete it */
simple_heap_delete(lRel, &tuple->t_self);
/*
- * We assume there can be only one match, so no need to scan
- * the rest of the table
+ * We assume there can be only one match, so no need to scan the
+ * rest of the table
*/
break;
}
@@ -387,10 +386,10 @@ static void
Async_UnlistenOnExit(int code, Datum arg)
{
/*
- * We need to start/commit a transaction for the unlisten, but if
- * there is already an active transaction we had better abort that one
- * first. Otherwise we'd end up committing changes that probably
- * ought to be discarded.
+ * We need to start/commit a transaction for the unlisten, but if there is
+ * already an active transaction we had better abort that one first.
+ * Otherwise we'd end up committing changes that probably ought to be
+ * discarded.
*/
AbortOutOfAnyTransaction();
/* Now we can do the unlisten */
@@ -404,14 +403,14 @@ Async_UnlistenOnExit(int code, Datum arg)
*--------------------------------------------------------------
* AtPrepare_Notify
*
- * This is called at the prepare phase of a two-phase
+ * This is called at the prepare phase of a two-phase
* transaction. Save the state for possible commit later.
*--------------------------------------------------------------
*/
void
AtPrepare_Notify(void)
{
- ListCell *p;
+ ListCell *p;
foreach(p, pendingNotifies)
{
@@ -423,8 +422,8 @@ AtPrepare_Notify(void)
/*
* We can clear the state immediately, rather than needing a separate
- * PostPrepare call, because if the transaction fails we'd just
- * discard the state anyway.
+ * PostPrepare call, because if the transaction fails we'd just discard
+ * the state anyway.
*/
ClearPendingNotifies();
}
@@ -464,12 +463,11 @@ AtCommit_Notify(void)
nulls[Natts_pg_listener];
if (pendingNotifies == NIL)
- return; /* no NOTIFY statements in this
- * transaction */
+ return; /* no NOTIFY statements in this transaction */
/*
- * NOTIFY is disabled if not normal processing mode. This test used to
- * be in xact.c, but it seems cleaner to do it here.
+ * NOTIFY is disabled if not normal processing mode. This test used to be
+ * in xact.c, but it seems cleaner to do it here.
*/
if (!IsNormalProcessingMode())
{
@@ -503,10 +501,10 @@ AtCommit_Notify(void)
if (listenerPID == MyProcPid)
{
/*
- * Self-notify: no need to bother with table update. Indeed,
- * we *must not* clear the notification field in this path, or
- * we could lose an outside notify, which'd be bad for
- * applications that ignore self-notify messages.
+ * Self-notify: no need to bother with table update. Indeed, we
+ * *must not* clear the notification field in this path, or we
+ * could lose an outside notify, which'd be bad for applications
+ * that ignore self-notify messages.
*/
if (Trace_notify)
@@ -521,27 +519,27 @@ AtCommit_Notify(void)
listenerPID);
/*
- * If someone has already notified this listener, we don't
- * bother modifying the table, but we do still send a SIGUSR2
- * signal, just in case that backend missed the earlier signal
- * for some reason. It's OK to send the signal first, because
- * the other guy can't read pg_listener until we unlock it.
+ * If someone has already notified this listener, we don't bother
+ * modifying the table, but we do still send a SIGUSR2 signal,
+ * just in case that backend missed the earlier signal for some
+ * reason. It's OK to send the signal first, because the other
+ * guy can't read pg_listener until we unlock it.
*/
if (kill(listenerPID, SIGUSR2) < 0)
{
/*
- * Get rid of pg_listener entry if it refers to a PID that
- * no longer exists. Presumably, that backend crashed
- * without deleting its pg_listener entries. This code
- * used to only delete the entry if errno==ESRCH, but as
- * far as I can see we should just do it for any failure
- * (certainly at least for EPERM too...)
+ * Get rid of pg_listener entry if it refers to a PID that no
+ * longer exists. Presumably, that backend crashed without
+ * deleting its pg_listener entries. This code used to only
+ * delete the entry if errno==ESRCH, but as far as I can see
+ * we should just do it for any failure (certainly at least
+ * for EPERM too...)
*/
simple_heap_delete(lRel, &lTuple->t_self);
}
else if (listener->notification == 0)
{
- HTSU_Result result;
+ HTSU_Result result;
ItemPointerData update_ctid;
TransactionId update_xmax;
@@ -551,17 +549,16 @@ AtCommit_Notify(void)
/*
* We cannot use simple_heap_update here because the tuple
* could have been modified by an uncommitted transaction;
- * specifically, since UNLISTEN releases exclusive lock on
- * the table before commit, the other guy could already
- * have tried to unlisten. There are no other cases where
- * we should be able to see an uncommitted update or
- * delete. Therefore, our response to a
- * HeapTupleBeingUpdated result is just to ignore it. We
- * do *not* wait for the other guy to commit --- that
- * would risk deadlock, and we don't want to block while
- * holding the table lock anyway for performance reasons.
- * We also ignore HeapTupleUpdated, which could occur if
- * the other guy commits between our heap_getnext and
+ * specifically, since UNLISTEN releases exclusive lock on the
+ * table before commit, the other guy could already have tried
+ * to unlisten. There are no other cases where we should be
+ * able to see an uncommitted update or delete. Therefore, our
+ * response to a HeapTupleBeingUpdated result is just to
+ * ignore it. We do *not* wait for the other guy to commit
+ * --- that would risk deadlock, and we don't want to block
+ * while holding the table lock anyway for performance
+ * reasons. We also ignore HeapTupleUpdated, which could occur
+ * if the other guy commits between our heap_getnext and
* heap_update calls.
*/
result = heap_update(lRel, &lTuple->t_self, rTuple,
@@ -603,10 +600,10 @@ AtCommit_Notify(void)
/*
* We do NOT release the lock on pg_listener here; we need to hold it
- * until end of transaction (which is about to happen, anyway) to
- * ensure that notified backends see our tuple updates when they look.
- * Else they might disregard the signal, which would make the
- * application programmer very unhappy.
+ * until end of transaction (which is about to happen, anyway) to ensure
+ * that notified backends see our tuple updates when they look. Else they
+ * might disregard the signal, which would make the application programmer
+ * very unhappy.
*/
heap_close(lRel, NoLock);
@@ -676,8 +673,7 @@ AtSubCommit_Notify(void)
GetCurrentTransactionNestLevel() - 2);
/*
- * We could try to eliminate duplicates here, but it seems not
- * worthwhile.
+ * We could try to eliminate duplicates here, but it seems not worthwhile.
*/
pendingNotifies = list_concat(parentPendingNotifies, pendingNotifies);
}
@@ -695,10 +691,10 @@ AtSubAbort_Notify(void)
* subxact are no longer interesting, and the space will be freed when
* CurTransactionContext is recycled.
*
- * This routine could be called more than once at a given nesting level
- * if there is trouble during subxact abort. Avoid dumping core by
- * using GetCurrentTransactionNestLevel as the indicator of how far
- * we need to prune the list.
+ * This routine could be called more than once at a given nesting level if
+ * there is trouble during subxact abort. Avoid dumping core by using
+ * GetCurrentTransactionNestLevel as the indicator of how far we need to
+ * prune the list.
*/
while (list_length(upperPendingNotifies) > my_level - 2)
{
@@ -731,9 +727,9 @@ NotifyInterruptHandler(SIGNAL_ARGS)
/*
* Note: this is a SIGNAL HANDLER. You must be very wary what you do
- * here. Some helpful soul had this routine sprinkled with TPRINTFs,
- * which would likely lead to corruption of stdio buffers if they were
- * ever turned on.
+ * here. Some helpful soul had this routine sprinkled with TPRINTFs, which
+ * would likely lead to corruption of stdio buffers if they were ever
+ * turned on.
*/
/* Don't joggle the elbow of proc_exit */
@@ -745,19 +741,18 @@ NotifyInterruptHandler(SIGNAL_ARGS)
bool save_ImmediateInterruptOK = ImmediateInterruptOK;
/*
- * We may be called while ImmediateInterruptOK is true; turn it
- * off while messing with the NOTIFY state. (We would have to
- * save and restore it anyway, because PGSemaphore operations
- * inside ProcessIncomingNotify() might reset it.)
+ * We may be called while ImmediateInterruptOK is true; turn it off
+ * while messing with the NOTIFY state. (We would have to save and
+ * restore it anyway, because PGSemaphore operations inside
+ * ProcessIncomingNotify() might reset it.)
*/
ImmediateInterruptOK = false;
/*
* I'm not sure whether some flavors of Unix might allow another
- * SIGUSR2 occurrence to recursively interrupt this routine. To
- * cope with the possibility, we do the same sort of dance that
- * EnableNotifyInterrupt must do --- see that routine for
- * comments.
+ * SIGUSR2 occurrence to recursively interrupt this routine. To cope
+ * with the possibility, we do the same sort of dance that
+ * EnableNotifyInterrupt must do --- see that routine for comments.
*/
notifyInterruptEnabled = 0; /* disable any recursive signal */
notifyInterruptOccurred = 1; /* do at least one iteration */
@@ -781,8 +776,7 @@ NotifyInterruptHandler(SIGNAL_ARGS)
}
/*
- * Restore ImmediateInterruptOK, and check for interrupts if
- * needed.
+ * Restore ImmediateInterruptOK, and check for interrupts if needed.
*/
ImmediateInterruptOK = save_ImmediateInterruptOK;
if (save_ImmediateInterruptOK)
@@ -791,8 +785,7 @@ NotifyInterruptHandler(SIGNAL_ARGS)
else
{
/*
- * In this path it is NOT SAFE to do much of anything, except
- * this:
+ * In this path it is NOT SAFE to do much of anything, except this:
*/
notifyInterruptOccurred = 1;
}
@@ -820,27 +813,25 @@ EnableNotifyInterrupt(void)
return; /* not really idle */
/*
- * This code is tricky because we are communicating with a signal
- * handler that could interrupt us at any point. If we just checked
- * notifyInterruptOccurred and then set notifyInterruptEnabled, we
- * could fail to respond promptly to a signal that happens in between
- * those two steps. (A very small time window, perhaps, but Murphy's
- * Law says you can hit it...) Instead, we first set the enable flag,
- * then test the occurred flag. If we see an unserviced interrupt has
- * occurred, we re-clear the enable flag before going off to do the
- * service work. (That prevents re-entrant invocation of
- * ProcessIncomingNotify() if another interrupt occurs.) If an
- * interrupt comes in between the setting and clearing of
- * notifyInterruptEnabled, then it will have done the service work and
- * left notifyInterruptOccurred zero, so we have to check again after
- * clearing enable. The whole thing has to be in a loop in case
- * another interrupt occurs while we're servicing the first. Once we
- * get out of the loop, enable is set and we know there is no
- * unserviced interrupt.
+ * This code is tricky because we are communicating with a signal handler
+ * that could interrupt us at any point. If we just checked
+ * notifyInterruptOccurred and then set notifyInterruptEnabled, we could
+ * fail to respond promptly to a signal that happens in between those two
+ * steps. (A very small time window, perhaps, but Murphy's Law says you
+ * can hit it...) Instead, we first set the enable flag, then test the
+ * occurred flag. If we see an unserviced interrupt has occurred, we
+ * re-clear the enable flag before going off to do the service work.
+ * (That prevents re-entrant invocation of ProcessIncomingNotify() if
+ * another interrupt occurs.) If an interrupt comes in between the setting
+ * and clearing of notifyInterruptEnabled, then it will have done the
+ * service work and left notifyInterruptOccurred zero, so we have to check
+ * again after clearing enable. The whole thing has to be in a loop in
+ * case another interrupt occurs while we're servicing the first. Once we
+ * get out of the loop, enable is set and we know there is no unserviced
+ * interrupt.
*
- * NB: an overenthusiastic optimizing compiler could easily break this
- * code. Hopefully, they all understand what "volatile" means these
- * days.
+ * NB: an overenthusiastic optimizing compiler could easily break this code.
+ * Hopefully, they all understand what "volatile" means these days.
*/
for (;;)
{
@@ -960,8 +951,7 @@ ProcessIncomingNotify(void)
* Rewrite the tuple with 0 in notification column.
*
* simple_heap_update is safe here because no one else would have
- * tried to UNLISTEN us, so there can be no uncommitted
- * changes.
+ * tried to UNLISTEN us, so there can be no uncommitted changes.
*/
rTuple = heap_modifytuple(lTuple, tdesc, value, nulls, repl);
simple_heap_update(lRel, &lTuple->t_self, rTuple);
@@ -975,18 +965,17 @@ ProcessIncomingNotify(void)
/*
* We do NOT release the lock on pg_listener here; we need to hold it
- * until end of transaction (which is about to happen, anyway) to
- * ensure that other backends see our tuple updates when they look.
- * Otherwise, a transaction started after this one might mistakenly
- * think it doesn't need to send this backend a new NOTIFY.
+ * until end of transaction (which is about to happen, anyway) to ensure
+ * that other backends see our tuple updates when they look. Otherwise, a
+ * transaction started after this one might mistakenly think it doesn't
+ * need to send this backend a new NOTIFY.
*/
heap_close(lRel, NoLock);
CommitTransactionCommand();
/*
- * Must flush the notify messages to ensure frontend gets them
- * promptly.
+ * Must flush the notify messages to ensure frontend gets them promptly.
*/
pq_flush();
@@ -1022,8 +1011,7 @@ NotifyMyFrontEnd(char *relname, int32 listenerPID)
/*
* NOTE: we do not do pq_flush() here. For a self-notify, it will
* happen at the end of the transaction, and for incoming notifies
- * ProcessIncomingNotify will do it after finding all the
- * notifies.
+ * ProcessIncomingNotify will do it after finding all the notifies.
*/
}
else
@@ -1052,11 +1040,11 @@ static void
ClearPendingNotifies(void)
{
/*
- * We used to have to explicitly deallocate the list members and
- * nodes, because they were malloc'd. Now, since we know they are
- * palloc'd in CurTransactionContext, we need not do that --- they'll
- * go away automatically at transaction exit. We need only reset the
- * list head pointer.
+ * We used to have to explicitly deallocate the list members and nodes,
+ * because they were malloc'd. Now, since we know they are palloc'd in
+ * CurTransactionContext, we need not do that --- they'll go away
+ * automatically at transaction exit. We need only reset the list head
+ * pointer.
*/
pendingNotifies = NIL;
}
@@ -1071,11 +1059,10 @@ notify_twophase_postcommit(TransactionId xid, uint16 info,
void *recdata, uint32 len)
{
/*
- * Set up to issue the NOTIFY at the end of my own
- * current transaction. (XXX this has some issues if my own
- * transaction later rolls back, or if there is any significant
- * delay before I commit. OK for now because we disallow
- * COMMIT PREPARED inside a transaction block.)
+ * Set up to issue the NOTIFY at the end of my own current transaction.
+ * (XXX this has some issues if my own transaction later rolls back, or if
+ * there is any significant delay before I commit. OK for now because we
+ * disallow COMMIT PREPARED inside a transaction block.)
*/
Async_Notify((char *) recdata);
}