Skip to content

Commit 6054b33

Browse files
committed
Keep the list of to-be-NOTIFYed names in a plain List palloc'd in
TopTransactionContext, rather than using Dllist. This simplifies and speeds up the code, and eliminates a former risk of coredump when out of memory (since the old code didn't bother to check for malloc failure). It also moves us one step closer to retiring Dllist...
1 parent 1f1ca18 commit 6054b33

File tree

1 file changed

+42
-66
lines changed

1 file changed

+42
-66
lines changed

src/backend/commands/async.c

Lines changed: 42 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.78 2001/06/12 05:55:49 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.79 2001/06/17 22:27:15 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -82,7 +82,6 @@
8282
#include "catalog/catname.h"
8383
#include "catalog/pg_listener.h"
8484
#include "commands/async.h"
85-
#include "lib/dllist.h"
8685
#include "libpq/libpq.h"
8786
#include "libpq/pqformat.h"
8887
#include "miscadmin.h"
@@ -100,10 +99,11 @@ extern CommandDest whereToSendOutput;
10099
/*
101100
* State for outbound notifies consists of a list of all relnames NOTIFYed
102101
* in the current transaction. We do not actually perform a NOTIFY until
103-
* and unless the transaction commits. pendingNotifies is NULL if no
104-
* NOTIFYs have been done in the current transaction.
102+
* and unless the transaction commits. pendingNotifies is NIL if no
103+
* NOTIFYs have been done in the current transaction. The List nodes and
104+
* referenced strings are all palloc'd in TopTransactionContext.
105105
*/
106-
static Dllist *pendingNotifies = NULL;
106+
static List *pendingNotifies = NIL;
107107

108108
/*
109109
* State for inbound notifies consists of two flags: one saying whether
@@ -121,16 +121,16 @@ static volatile int notifyInterruptOccurred = 0;
121121
/* True if we've registered an on_shmem_exit cleanup */
122122
static bool unlistenExitRegistered = false;
123123

124+
bool Trace_notify = false;
125+
124126

125127
static void Async_UnlistenAll(void);
126128
static void Async_UnlistenOnExit(void);
127129
static void ProcessIncomingNotify(void);
128130
static void NotifyMyFrontEnd(char *relname, int32 listenerPID);
129-
static int AsyncExistsPendingNotify(char *relname);
131+
static bool AsyncExistsPendingNotify(const char *relname);
130132
static void ClearPendingNotifies(void);
131133

132-
bool Trace_notify = false;
133-
134134

135135
/*
136136
*--------------------------------------------------------------
@@ -150,26 +150,23 @@ bool Trace_notify = false;
150150
void
151151
Async_Notify(char *relname)
152152
{
153-
char *notifyName;
154-
155153
if (Trace_notify)
156154
elog(DEBUG, "Async_Notify: %s", relname);
157155

158-
if (!pendingNotifies)
159-
pendingNotifies = DLNewList();
160156
/* no point in making duplicate entries in the list ... */
161-
if (!AsyncExistsPendingNotify(relname))
157+
if (! AsyncExistsPendingNotify(relname))
162158
{
163-
164159
/*
165-
* We allocate list memory from the global malloc pool to ensure
166-
* that it will live until we want to use it. This is probably
167-
* not necessary any longer, since we will use it before the end
168-
* of the transaction. DLList only knows how to use malloc()
169-
* anyway, but we could probably palloc() the strings...
160+
* The name list needs to live until end of transaction, so
161+
* store it in the top transaction context.
170162
*/
171-
notifyName = strdup(relname);
172-
DLAddHead(pendingNotifies, DLNewElem(notifyName));
163+
MemoryContext oldcontext;
164+
165+
oldcontext = MemoryContextSwitchTo(TopTransactionContext);
166+
167+
pendingNotifies = lcons(pstrdup(relname), pendingNotifies);
168+
169+
MemoryContextSwitchTo(oldcontext);
173170
}
174171
}
175172

@@ -352,7 +349,7 @@ Async_Unlisten(char *relname, int pid)
352349
*--------------------------------------------------------------
353350
*/
354351
static void
355-
Async_UnlistenAll()
352+
Async_UnlistenAll(void)
356353
{
357354
Relation lRel;
358355
TupleDesc tdesc;
@@ -401,7 +398,6 @@ Async_UnlistenAll()
401398
static void
402399
Async_UnlistenOnExit(void)
403400
{
404-
405401
/*
406402
* We need to start/commit a transaction for the unlisten, but if
407403
* there is already an active transaction we had better abort that one
@@ -438,7 +434,7 @@ Async_UnlistenOnExit(void)
438434
*--------------------------------------------------------------
439435
*/
440436
void
441-
AtCommit_Notify()
437+
AtCommit_Notify(void)
442438
{
443439
Relation lRel;
444440
TupleDesc tdesc;
@@ -449,7 +445,7 @@ AtCommit_Notify()
449445
char repl[Natts_pg_listener],
450446
nulls[Natts_pg_listener];
451447

452-
if (!pendingNotifies)
448+
if (pendingNotifies == NIL)
453449
return; /* no NOTIFY statements in this
454450
* transaction */
455451

@@ -579,7 +575,7 @@ AtCommit_Notify()
579575
*--------------------------------------------------------------
580576
*/
581577
void
582-
AtAbort_Notify()
578+
AtAbort_Notify(void)
583579
{
584580
ClearPendingNotifies();
585581
}
@@ -601,7 +597,6 @@ AtAbort_Notify()
601597
* per above
602598
*--------------------------------------------------------------
603599
*/
604-
605600
void
606601
Async_NotifyHandler(SIGNAL_ARGS)
607602
{
@@ -671,7 +666,6 @@ Async_NotifyHandler(SIGNAL_ARGS)
671666
* PostgresMain calls this the first time.
672667
* --------------------------------------------------------------
673668
*/
674-
675669
void
676670
EnableNotifyInterrupt(void)
677671
{
@@ -729,7 +723,6 @@ EnableNotifyInterrupt(void)
729723
* is disabled until the next EnableNotifyInterrupt call.
730724
* --------------------------------------------------------------
731725
*/
732-
733726
void
734727
DisableNotifyInterrupt(void)
735728
{
@@ -848,8 +841,9 @@ ProcessIncomingNotify(void)
848841
elog(DEBUG, "ProcessIncomingNotify: done");
849842
}
850843

851-
/* Send NOTIFY message to my front end. */
852-
844+
/*
845+
* Send NOTIFY message to my front end.
846+
*/
853847
static void
854848
NotifyMyFrontEnd(char *relname, int32 listenerPID)
855849
{
@@ -874,50 +868,32 @@ NotifyMyFrontEnd(char *relname, int32 listenerPID)
874868
elog(NOTICE, "NOTIFY for %s", relname);
875869
}
876870

877-
/* Does pendingNotifies include the given relname?
878-
*
879-
* NB: not called unless pendingNotifies != NULL.
880-
*/
881-
882-
static int
883-
AsyncExistsPendingNotify(char *relname)
871+
/* Does pendingNotifies include the given relname? */
872+
static bool
873+
AsyncExistsPendingNotify(const char *relname)
884874
{
885-
Dlelem *p;
875+
List *p;
886876

887-
for (p = DLGetHead(pendingNotifies);
888-
p != NULL;
889-
p = DLGetSucc(p))
877+
foreach(p, pendingNotifies)
890878
{
891879
/* Use NAMEDATALEN for relname comparison. DZ - 26-08-1996 */
892-
if (strncmp((const char *) DLE_VAL(p), relname, NAMEDATALEN) == 0)
893-
return 1;
880+
if (strncmp((const char *) lfirst(p), relname, NAMEDATALEN) == 0)
881+
return true;
894882
}
895883

896-
return 0;
884+
return false;
897885
}
898886

899887
/* Clear the pendingNotifies list. */
900-
901888
static void
902-
ClearPendingNotifies()
889+
ClearPendingNotifies(void)
903890
{
904-
Dlelem *p;
905-
906-
if (pendingNotifies)
907-
{
908-
909-
/*
910-
* Since the referenced strings are malloc'd, we have to scan the
911-
* list and delete them individually. If we used palloc for the
912-
* strings then we could just do DLFreeList to get rid of both the
913-
* list nodes and the list base...
914-
*/
915-
while ((p = DLRemHead(pendingNotifies)) != NULL)
916-
{
917-
free(DLE_VAL(p));
918-
DLFreeElem(p);
919-
}
920-
DLFreeList(pendingNotifies);
921-
pendingNotifies = NULL;
922-
}
891+
/*
892+
* We used to have to explicitly deallocate the list members and nodes,
893+
* because they were malloc'd. Now, since we know they are palloc'd
894+
* in TopTransactionContext, we need not do that --- they'll go away
895+
* automatically at transaction exit. We need only reset the list head
896+
* pointer.
897+
*/
898+
pendingNotifies = NIL;
923899
}

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