@ -350,12 +350,12 @@ static volatile sig_atomic_t notifyInterruptOccurred = 0;
/* True if we've registered an on_shmem_exit cleanup */
static bool unlistenExitRegistered = false ;
/* True if we're currently registered as a listener in asyncQueueControl */
static bool amRegisteredListener = false ;
/* has this backend sent notifications in the current transaction? */
static bool backendHasSentNotifications = false ;
/* has this backend executed its first LISTEN in the current transaction? */
static bool backendHasExecutedInitialListen = false ;
/* GUC parameter */
bool Trace_notify = false ;
@ -724,6 +724,7 @@ static void
Async_UnlistenOnExit ( int code , Datum arg )
{
Exec_UnlistenAllCommit ( ) ;
asyncQueueUnregister ( ) ;
}
/*
@ -768,8 +769,6 @@ PreCommit_Notify(void)
if ( Trace_notify )
elog ( DEBUG1 , " PreCommit_Notify " ) ;
Assert ( backendHasExecutedInitialListen = = false ) ;
/* Preflight for any pending listen/unlisten actions */
foreach ( p , pendingActions )
{
@ -892,11 +891,9 @@ AtCommit_Notify(void)
}
}
/*
* If we did an initial LISTEN , listenChannels now has the entry , so we no
* longer need or want the flag to be set .
*/
backendHasExecutedInitialListen = false ;
/* If no longer listening to anything, get out of listener array */
if ( amRegisteredListener & & listenChannels = = NIL )
asyncQueueUnregister ( ) ;
/* And clean up */
ClearPendingActionsAndNotifies ( ) ;
@ -914,19 +911,12 @@ Exec_ListenPreCommit(void)
* Nothing to do if we are already listening to something , nor if we
* already ran this routine in this transaction .
*/
if ( listenChannels ! = NIL | | backendHasExecutedInitialListen )
if ( amRegisteredListener )
return ;
if ( Trace_notify )
elog ( DEBUG1 , " Exec_ListenPreCommit(%d) " , MyProcPid ) ;
/*
* We need this variable to detect an aborted initial LISTEN . In that case
* we would set up our pointer but not listen on any channel . This flag
* gets cleared in AtCommit_Notify or AtAbort_Notify ( ) .
*/
backendHasExecutedInitialListen = true ;
/*
* Before registering , make sure we will unlisten before dying . ( Note :
* this action does not get undone if we abort later . )
@ -950,6 +940,9 @@ Exec_ListenPreCommit(void)
QUEUE_BACKEND_PID ( MyBackendId ) = MyProcPid ;
LWLockRelease ( AsyncQueueLock ) ;
/* Now we are listed in the global array, so remember we're listening */
amRegisteredListener = true ;
/*
* Try to move our pointer forward as far as possible . This will skip over
* already - committed notifications . Still , we could get notifications that
@ -1022,10 +1015,6 @@ Exec_UnlistenCommit(const char *channel)
* We do not complain about unlistening something not being listened ;
* should we ?
*/
/* If no longer listening to anything, get out of listener array */
if ( listenChannels = = NIL )
asyncQueueUnregister ( ) ;
}
/*
@ -1041,8 +1030,6 @@ Exec_UnlistenAllCommit(void)
list_free_deep ( listenChannels ) ;
listenChannels = NIL ;
asyncQueueUnregister ( ) ;
}
/*
@ -1160,6 +1147,9 @@ asyncQueueUnregister(void)
Assert ( listenChannels = = NIL ) ; /* else caller error */
if ( ! amRegisteredListener ) /* nothing to do */
return ;
LWLockAcquire ( AsyncQueueLock , LW_SHARED ) ;
/* check if entry is valid and oldest ... */
advanceTail = ( MyProcPid = = QUEUE_BACKEND_PID ( MyBackendId ) ) & &
@ -1168,6 +1158,9 @@ asyncQueueUnregister(void)
QUEUE_BACKEND_PID ( MyBackendId ) = InvalidPid ;
LWLockRelease ( AsyncQueueLock ) ;
/* mark ourselves as no longer listed in the global array */
amRegisteredListener = false ;
/* If we were the laziest backend, try to advance the tail pointer */
if ( advanceTail )
asyncQueueAdvanceTail ( ) ;
@ -1524,21 +1517,12 @@ void
AtAbort_Notify ( void )
{
/*
* If we LISTEN but then roll back the transaction we have set our pointer
* but have not made any entry in listenChannels . In that case , remove our
* poin ter again .
* If we LISTEN but then roll back the transaction after PreCommit_Notify ,
* we have registered as a listener but have not made any entry in
* listenChannels . In that case , deregis ter again .
*/
if ( backendHasExecutedInitialListen )
{
/*
* Checking listenChannels should be redundant but it can ' t hurt doing
* it for safety reasons .
*/
if ( listenChannels = = NIL )
asyncQueueUnregister ( ) ;
backendHasExecutedInitialListen = false ;
}
if ( amRegisteredListener & & listenChannels = = NIL )
asyncQueueUnregister ( ) ;
/* And clean up */
ClearPendingActionsAndNotifies ( ) ;