LCOV - differential code coverage report
Current view: top level - src/backend/utils/resowner - resowner.c (source / functions) Coverage Total Hit UNC LBC UIC UBC GBC GIC GNC CBC EUB ECB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 85.5 % 463 396 3 27 36 1 10 246 21 119 56 247 3
Current Date: 2023-04-08 17:13:01 Functions: 86.6 % 67 58 9 55 3 9 58
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 [..60] days: 89.5 % 19 17 2 17
Legend: Lines: hit not hit (180,240] days: 80.0 % 5 4 1 4
(240..) days: 85.4 % 439 375 27 36 1 10 246 119 48 235
Function coverage date bins:
[..60] days: 100.0 % 3 3 3
(240..) days: 44.0 % 125 55 9 55 7 54

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * resowner.c
                                  4                 :  *    POSTGRES resource owner management code.
                                  5                 :  *
                                  6                 :  * Query-lifespan resources are tracked by associating them with
                                  7                 :  * ResourceOwner objects.  This provides a simple mechanism for ensuring
                                  8                 :  * that such resources are freed at the right time.
                                  9                 :  * See utils/resowner/README for more info.
                                 10                 :  *
                                 11                 :  *
                                 12                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
                                 13                 :  * Portions Copyright (c) 1994, Regents of the University of California
                                 14                 :  *
                                 15                 :  *
                                 16                 :  * IDENTIFICATION
                                 17                 :  *    src/backend/utils/resowner/resowner.c
                                 18                 :  *
                                 19                 :  *-------------------------------------------------------------------------
                                 20                 :  */
                                 21                 : #include "postgres.h"
                                 22                 : 
                                 23                 : #include "common/cryptohash.h"
                                 24                 : #include "common/hashfn.h"
                                 25                 : #include "common/hmac.h"
                                 26                 : #include "jit/jit.h"
                                 27                 : #include "storage/bufmgr.h"
                                 28                 : #include "storage/ipc.h"
                                 29                 : #include "storage/predicate.h"
                                 30                 : #include "storage/proc.h"
                                 31                 : #include "utils/memutils.h"
                                 32                 : #include "utils/rel.h"
                                 33                 : #include "utils/resowner_private.h"
                                 34                 : #include "utils/snapmgr.h"
                                 35                 : 
                                 36                 : 
                                 37                 : /*
                                 38                 :  * All resource IDs managed by this code are required to fit into a Datum,
                                 39                 :  * which is fine since they are generally pointers or integers.
                                 40                 :  *
                                 41                 :  * Provide Datum conversion macros for a couple of things that are really
                                 42                 :  * just "int".
                                 43                 :  */
                                 44                 : #define FileGetDatum(file) Int32GetDatum(file)
                                 45                 : #define DatumGetFile(datum) ((File) DatumGetInt32(datum))
                                 46                 : #define BufferGetDatum(buffer) Int32GetDatum(buffer)
                                 47                 : #define DatumGetBuffer(datum) ((Buffer) DatumGetInt32(datum))
                                 48                 : 
                                 49                 : /*
                                 50                 :  * ResourceArray is a common structure for storing all types of resource IDs.
                                 51                 :  *
                                 52                 :  * We manage small sets of resource IDs by keeping them in a simple array:
                                 53                 :  * itemsarr[k] holds an ID, for 0 <= k < nitems <= maxitems = capacity.
                                 54                 :  *
                                 55                 :  * If a set grows large, we switch over to using open-addressing hashing.
                                 56                 :  * Then, itemsarr[] is a hash table of "capacity" slots, with each
                                 57                 :  * slot holding either an ID or "invalidval".  nitems is the number of valid
                                 58                 :  * items present; if it would exceed maxitems, we enlarge the array and
                                 59                 :  * re-hash.  In this mode, maxitems should be rather less than capacity so
                                 60                 :  * that we don't waste too much time searching for empty slots.
                                 61                 :  *
                                 62                 :  * In either mode, lastidx remembers the location of the last item inserted
                                 63                 :  * or returned by GetAny; this speeds up searches in ResourceArrayRemove.
                                 64                 :  */
                                 65                 : typedef struct ResourceArray
                                 66                 : {
                                 67                 :     Datum      *itemsarr;       /* buffer for storing values */
                                 68                 :     Datum       invalidval;     /* value that is considered invalid */
                                 69                 :     uint32      capacity;       /* allocated length of itemsarr[] */
                                 70                 :     uint32      nitems;         /* how many items are stored in items array */
                                 71                 :     uint32      maxitems;       /* current limit on nitems before enlarging */
                                 72                 :     uint32      lastidx;        /* index of last item returned by GetAny */
                                 73                 : } ResourceArray;
                                 74                 : 
                                 75                 : /*
                                 76                 :  * Initially allocated size of a ResourceArray.  Must be power of two since
                                 77                 :  * we'll use (arraysize - 1) as mask for hashing.
                                 78                 :  */
                                 79                 : #define RESARRAY_INIT_SIZE 16
                                 80                 : 
                                 81                 : /*
                                 82                 :  * When to switch to hashing vs. simple array logic in a ResourceArray.
                                 83                 :  */
                                 84                 : #define RESARRAY_MAX_ARRAY 64
                                 85                 : #define RESARRAY_IS_ARRAY(resarr) ((resarr)->capacity <= RESARRAY_MAX_ARRAY)
                                 86                 : 
                                 87                 : /*
                                 88                 :  * How many items may be stored in a resource array of given capacity.
                                 89                 :  * When this number is reached, we must resize.
                                 90                 :  */
                                 91                 : #define RESARRAY_MAX_ITEMS(capacity) \
                                 92                 :     ((capacity) <= RESARRAY_MAX_ARRAY ? (capacity) : (capacity)/4 * 3)
                                 93                 : 
                                 94                 : /*
                                 95                 :  * To speed up bulk releasing or reassigning locks from a resource owner to
                                 96                 :  * its parent, each resource owner has a small cache of locks it owns. The
                                 97                 :  * lock manager has the same information in its local lock hash table, and
                                 98                 :  * we fall back on that if cache overflows, but traversing the hash table
                                 99                 :  * is slower when there are a lot of locks belonging to other resource owners.
                                100                 :  *
                                101                 :  * MAX_RESOWNER_LOCKS is the size of the per-resource owner cache. It's
                                102                 :  * chosen based on some testing with pg_dump with a large schema. When the
                                103                 :  * tests were done (on 9.2), resource owners in a pg_dump run contained up
                                104                 :  * to 9 locks, regardless of the schema size, except for the top resource
                                105                 :  * owner which contained much more (overflowing the cache). 15 seems like a
                                106                 :  * nice round number that's somewhat higher than what pg_dump needs. Note that
                                107                 :  * making this number larger is not free - the bigger the cache, the slower
                                108                 :  * it is to release locks (in retail), when a resource owner holds many locks.
                                109                 :  */
                                110                 : #define MAX_RESOWNER_LOCKS 15
                                111                 : 
                                112                 : /*
                                113                 :  * ResourceOwner objects look like this
                                114                 :  */
                                115                 : typedef struct ResourceOwnerData
                                116                 : {
                                117                 :     ResourceOwner parent;       /* NULL if no parent (toplevel owner) */
                                118                 :     ResourceOwner firstchild;   /* head of linked list of children */
                                119                 :     ResourceOwner nextchild;    /* next child of same parent */
                                120                 :     const char *name;           /* name (just for debugging) */
                                121                 : 
                                122                 :     /* We have built-in support for remembering: */
                                123                 :     ResourceArray bufferarr;    /* owned buffers */
                                124                 :     ResourceArray bufferioarr;  /* in-progress buffer IO */
                                125                 :     ResourceArray catrefarr;    /* catcache references */
                                126                 :     ResourceArray catlistrefarr;    /* catcache-list pins */
                                127                 :     ResourceArray relrefarr;    /* relcache references */
                                128                 :     ResourceArray planrefarr;   /* plancache references */
                                129                 :     ResourceArray tupdescarr;   /* tupdesc references */
                                130                 :     ResourceArray snapshotarr;  /* snapshot references */
                                131                 :     ResourceArray filearr;      /* open temporary files */
                                132                 :     ResourceArray dsmarr;       /* dynamic shmem segments */
                                133                 :     ResourceArray jitarr;       /* JIT contexts */
                                134                 :     ResourceArray cryptohasharr;    /* cryptohash contexts */
                                135                 :     ResourceArray hmacarr;      /* HMAC contexts */
                                136                 : 
                                137                 :     /* We can remember up to MAX_RESOWNER_LOCKS references to local locks. */
                                138                 :     int         nlocks;         /* number of owned locks */
                                139                 :     LOCALLOCK  *locks[MAX_RESOWNER_LOCKS];  /* list of owned locks */
                                140                 : }           ResourceOwnerData;
                                141                 : 
                                142                 : 
                                143                 : /*****************************************************************************
                                144                 :  *    GLOBAL MEMORY                                                          *
                                145                 :  *****************************************************************************/
                                146                 : 
                                147                 : ResourceOwner CurrentResourceOwner = NULL;
                                148                 : ResourceOwner CurTransactionResourceOwner = NULL;
                                149                 : ResourceOwner TopTransactionResourceOwner = NULL;
                                150                 : ResourceOwner AuxProcessResourceOwner = NULL;
                                151                 : 
                                152                 : /*
                                153                 :  * List of add-on callbacks for resource releasing
                                154                 :  */
                                155                 : typedef struct ResourceReleaseCallbackItem
                                156                 : {
                                157                 :     struct ResourceReleaseCallbackItem *next;
                                158                 :     ResourceReleaseCallback callback;
                                159                 :     void       *arg;
                                160                 : } ResourceReleaseCallbackItem;
                                161                 : 
                                162                 : static ResourceReleaseCallbackItem *ResourceRelease_callbacks = NULL;
                                163                 : 
                                164                 : 
                                165                 : /* Internal routines */
                                166                 : static void ResourceArrayInit(ResourceArray *resarr, Datum invalidval);
                                167                 : static void ResourceArrayEnlarge(ResourceArray *resarr);
                                168                 : static void ResourceArrayAdd(ResourceArray *resarr, Datum value);
                                169                 : static bool ResourceArrayRemove(ResourceArray *resarr, Datum value);
                                170                 : static bool ResourceArrayGetAny(ResourceArray *resarr, Datum *value);
                                171                 : static void ResourceArrayFree(ResourceArray *resarr);
                                172                 : static void ResourceOwnerReleaseInternal(ResourceOwner owner,
                                173                 :                                          ResourceReleasePhase phase,
                                174                 :                                          bool isCommit,
                                175                 :                                          bool isTopLevel);
                                176                 : static void ReleaseAuxProcessResourcesCallback(int code, Datum arg);
                                177                 : static void PrintRelCacheLeakWarning(Relation rel);
                                178                 : static void PrintPlanCacheLeakWarning(CachedPlan *plan);
                                179                 : static void PrintTupleDescLeakWarning(TupleDesc tupdesc);
                                180                 : static void PrintSnapshotLeakWarning(Snapshot snapshot);
                                181                 : static void PrintFileLeakWarning(File file);
                                182                 : static void PrintDSMLeakWarning(dsm_segment *seg);
                                183                 : static void PrintCryptoHashLeakWarning(Datum handle);
                                184                 : static void PrintHMACLeakWarning(Datum handle);
                                185                 : 
                                186                 : 
                                187                 : /*****************************************************************************
                                188                 :  *    INTERNAL ROUTINES                                                      *
                                189                 :  *****************************************************************************/
                                190                 : 
                                191                 : 
                                192                 : /*
                                193                 :  * Initialize a ResourceArray
                                194                 :  */
                                195                 : static void
 2630 tgl                       196 GIC    13078767 : ResourceArrayInit(ResourceArray *resarr, Datum invalidval)
 2630 tgl                       197 ECB             : {
                                198                 :     /* Assert it's empty */
 2630 tgl                       199 GIC    13078767 :     Assert(resarr->itemsarr == NULL);
 2630 tgl                       200 CBC    13078767 :     Assert(resarr->capacity == 0);
                                201        13078767 :     Assert(resarr->nitems == 0);
                                202        13078767 :     Assert(resarr->maxitems == 0);
 2630 tgl                       203 ECB             :     /* Remember the appropriate "invalid" value */
 2630 tgl                       204 GIC    13078767 :     resarr->invalidval = invalidval;
 2630 tgl                       205 ECB             :     /* We don't allocate any storage until needed */
 2630 tgl                       206 GIC    13078767 : }
 2630 tgl                       207 ECB             : 
                                208                 : /*
                                209                 :  * Make sure there is room for at least one more resource in an array.
                                210                 :  *
                                211                 :  * This is separate from actually inserting a resource because if we run out
                                212                 :  * of memory, it's critical to do so *before* acquiring the resource.
                                213                 :  */
                                214                 : static void
 2630 tgl                       215 GIC   208923634 : ResourceArrayEnlarge(ResourceArray *resarr)
 2630 tgl                       216 ECB             : {
                                217                 :     uint32      i,
                                218                 :                 oldcap,
                                219                 :                 newcap;
                                220                 :     Datum      *olditemsarr;
                                221                 :     Datum      *newitemsarr;
                                222                 : 
 2630 tgl                       223 GIC   208923634 :     if (resarr->nitems < resarr->maxitems)
 2630 tgl                       224 CBC   205506208 :         return;                 /* no work needed */
 2630 tgl                       225 ECB             : 
 2630 tgl                       226 GIC     3417426 :     olditemsarr = resarr->itemsarr;
 2630 tgl                       227 CBC     3417426 :     oldcap = resarr->capacity;
 2630 tgl                       228 ECB             : 
                                229                 :     /* Double the capacity of the array (capacity must stay a power of 2!) */
 2630 tgl                       230 GIC     3417426 :     newcap = (oldcap > 0) ? oldcap * 2 : RESARRAY_INIT_SIZE;
 2630 tgl                       231 CBC     3417426 :     newitemsarr = (Datum *) MemoryContextAlloc(TopMemoryContext,
 2630 tgl                       232 ECB             :                                                newcap * sizeof(Datum));
 2630 tgl                       233 GIC    59757586 :     for (i = 0; i < newcap; i++)
 2630 tgl                       234 CBC    56340160 :         newitemsarr[i] = resarr->invalidval;
 2630 tgl                       235 ECB             : 
                                236                 :     /* We assume we can't fail below this point, so OK to scribble on resarr */
 2630 tgl                       237 GIC     3417426 :     resarr->itemsarr = newitemsarr;
 2630 tgl                       238 CBC     3417426 :     resarr->capacity = newcap;
                                239         3417426 :     resarr->maxitems = RESARRAY_MAX_ITEMS(newcap);
                                240         3417426 :     resarr->nitems = 0;
 2630 tgl                       241 ECB             : 
 2630 tgl                       242 GIC     3417426 :     if (olditemsarr != NULL)
 2630 tgl                       243 ECB             :     {
                                244                 :         /*
                                245                 :          * Transfer any pre-existing entries into the new array; they don't
                                246                 :          * necessarily go where they were before, so this simple logic is the
                                247                 :          * best way.  Note that if we were managing the set as a simple array,
                                248                 :          * the entries after nitems are garbage, but that shouldn't matter
                                249                 :          * because we won't get here unless nitems was equal to oldcap.
                                250                 :          */
 2630 tgl                       251 GIC      953306 :         for (i = 0; i < oldcap; i++)
 2630 tgl                       252 ECB             :         {
 2630 tgl                       253 GIC      939680 :             if (olditemsarr[i] != resarr->invalidval)
 2630 tgl                       254 CBC      769696 :                 ResourceArrayAdd(resarr, olditemsarr[i]);
 2630 tgl                       255 ECB             :         }
                                256                 : 
                                257                 :         /* And release old array. */
 2630 tgl                       258 GIC       13626 :         pfree(olditemsarr);
 2630 tgl                       259 ECB             :     }
                                260                 : 
 2630 tgl                       261 GIC     3417426 :     Assert(resarr->nitems < resarr->maxitems);
 2630 tgl                       262 ECB             : }
                                263                 : 
                                264                 : /*
                                265                 :  * Add a resource to ResourceArray
                                266                 :  *
                                267                 :  * Caller must have previously done ResourceArrayEnlarge()
                                268                 :  */
                                269                 : static void
 2630 tgl                       270 GIC   206595945 : ResourceArrayAdd(ResourceArray *resarr, Datum value)
 2630 tgl                       271 ECB             : {
                                272                 :     uint32      idx;
                                273                 : 
 2630 tgl                       274 GIC   206595945 :     Assert(value != resarr->invalidval);
 2630 tgl                       275 CBC   206595945 :     Assert(resarr->nitems < resarr->maxitems);
 2630 tgl                       276 ECB             : 
 2630 tgl                       277 GIC   206595945 :     if (RESARRAY_IS_ARRAY(resarr))
 2630 tgl                       278 ECB             :     {
                                279                 :         /* Append to linear array. */
 2630 tgl                       280 GIC   205411741 :         idx = resarr->nitems;
 2630 tgl                       281 ECB             :     }
                                282                 :     else
                                283                 :     {
                                284                 :         /* Insert into first free slot at or after hash location. */
 2630 tgl                       285 GIC     1184204 :         uint32      mask = resarr->capacity - 1;
 2630 tgl                       286 ECB             : 
 2630 tgl                       287 GIC     1184204 :         idx = DatumGetUInt32(hash_any((void *) &value, sizeof(value))) & mask;
 2630 tgl                       288 ECB             :         for (;;)
                                289                 :         {
 2630 tgl                       290 GIC   392068502 :             if (resarr->itemsarr[idx] == resarr->invalidval)
 2630 tgl                       291 CBC     1184204 :                 break;
                                292       390884298 :             idx = (idx + 1) & mask;
 2630 tgl                       293 ECB             :         }
                                294                 :     }
 2630 tgl                       295 GIC   206595945 :     resarr->lastidx = idx;
 2630 tgl                       296 CBC   206595945 :     resarr->itemsarr[idx] = value;
                                297       206595945 :     resarr->nitems++;
                                298       206595945 : }
 2630 tgl                       299 ECB             : 
                                300                 : /*
                                301                 :  * Remove a resource from ResourceArray
                                302                 :  *
                                303                 :  * Returns true on success, false if resource was not found.
                                304                 :  *
                                305                 :  * Note: if same resource ID appears more than once, one instance is removed.
                                306                 :  */
                                307                 : static bool
 2630 tgl                       308 GIC   205826244 : ResourceArrayRemove(ResourceArray *resarr, Datum value)
 2630 tgl                       309 ECB             : {
                                310                 :     uint32      i,
                                311                 :                 idx,
 2630 tgl                       312 GIC   205826244 :                 lastidx = resarr->lastidx;
 2630 tgl                       313 ECB             : 
 2630 tgl                       314 GIC   205826244 :     Assert(value != resarr->invalidval);
 2630 tgl                       315 ECB             : 
                                316                 :     /* Search through all items, but try lastidx first. */
 2630 tgl                       317 GIC   205826244 :     if (RESARRAY_IS_ARRAY(resarr))
 2630 tgl                       318 ECB             :     {
 2630 tgl                       319 GIC   205151992 :         if (lastidx < resarr->nitems &&
 2630 tgl                       320 CBC   205151992 :             resarr->itemsarr[lastidx] == value)
 2630 tgl                       321 ECB             :         {
 2630 tgl                       322 GIC   199281187 :             resarr->itemsarr[lastidx] = resarr->itemsarr[resarr->nitems - 1];
 2630 tgl                       323 CBC   199281187 :             resarr->nitems--;
 2630 tgl                       324 ECB             :             /* Update lastidx to make reverse-order removals fast. */
 2630 tgl                       325 GIC   199281187 :             resarr->lastidx = resarr->nitems - 1;
 2630 tgl                       326 CBC   199281187 :             return true;
 2630 tgl                       327 ECB             :         }
 2630 tgl                       328 GIC    12783604 :         for (i = 0; i < resarr->nitems; i++)
 2630 tgl                       329 ECB             :         {
 2630 tgl                       330 GIC    12783604 :             if (resarr->itemsarr[i] == value)
 2630 tgl                       331 ECB             :             {
 2630 tgl                       332 GIC     5870805 :                 resarr->itemsarr[i] = resarr->itemsarr[resarr->nitems - 1];
 2630 tgl                       333 CBC     5870805 :                 resarr->nitems--;
 2630 tgl                       334 ECB             :                 /* Update lastidx to make reverse-order removals fast. */
 2630 tgl                       335 GIC     5870805 :                 resarr->lastidx = resarr->nitems - 1;
 2630 tgl                       336 CBC     5870805 :                 return true;
 2630 tgl                       337 ECB             :             }
                                338                 :         }
                                339                 :     }
                                340                 :     else
                                341                 :     {
 2630 tgl                       342 GIC      674252 :         uint32      mask = resarr->capacity - 1;
 2630 tgl                       343 ECB             : 
 2630 tgl                       344 GIC      674252 :         if (lastidx < resarr->capacity &&
 2630 tgl                       345 CBC      674252 :             resarr->itemsarr[lastidx] == value)
 2630 tgl                       346 ECB             :         {
 2630 tgl                       347 GIC      199252 :             resarr->itemsarr[lastidx] = resarr->invalidval;
 2630 tgl                       348 CBC      199252 :             resarr->nitems--;
                                349          199252 :             return true;
 2630 tgl                       350 ECB             :         }
 2630 tgl                       351 GIC      475000 :         idx = DatumGetUInt32(hash_any((void *) &value, sizeof(value))) & mask;
 2630 tgl                       352 CBC   171789826 :         for (i = 0; i < resarr->capacity; i++)
 2630 tgl                       353 ECB             :         {
 2630 tgl                       354 GIC   171789826 :             if (resarr->itemsarr[idx] == value)
 2630 tgl                       355 ECB             :             {
 2630 tgl                       356 GIC      475000 :                 resarr->itemsarr[idx] = resarr->invalidval;
 2630 tgl                       357 CBC      475000 :                 resarr->nitems--;
                                358          475000 :                 return true;
 2630 tgl                       359 ECB             :             }
 2630 tgl                       360 GIC   171314826 :             idx = (idx + 1) & mask;
 2630 tgl                       361 ECB             :         }
                                362                 :     }
                                363                 : 
 2630 tgl                       364 UIC           0 :     return false;
 2630 tgl                       365 EUB             : }
                                366                 : 
                                367                 : /*
                                368                 :  * Get any convenient entry in a ResourceArray.
                                369                 :  *
                                370                 :  * "Convenient" is defined as "easy for ResourceArrayRemove to remove";
                                371                 :  * we help that along by setting lastidx to match.  This avoids O(N^2) cost
                                372                 :  * when removing all ResourceArray items during ResourceOwner destruction.
                                373                 :  *
                                374                 :  * Returns true if we found an element, or false if the array is empty.
                                375                 :  */
                                376                 : static bool
 2630 tgl                       377 GIC    13180874 : ResourceArrayGetAny(ResourceArray *resarr, Datum *value)
 2630 tgl                       378 ECB             : {
 2630 tgl                       379 GIC    13180874 :     if (resarr->nitems == 0)
 2630 tgl                       380 CBC    13088006 :         return false;
 2630 tgl                       381 ECB             : 
 2630 tgl                       382 GIC       92868 :     if (RESARRAY_IS_ARRAY(resarr))
 2630 tgl                       383 ECB             :     {
                                384                 :         /* Linear array: just return the first element. */
 2630 tgl                       385 GIC       83885 :         resarr->lastidx = 0;
 2630 tgl                       386 ECB             :     }
                                387                 :     else
                                388                 :     {
                                389                 :         /* Hash: search forward from wherever we were last. */
 2630 tgl                       390 GIC        8983 :         uint32      mask = resarr->capacity - 1;
 2630 tgl                       391 ECB             : 
                                392                 :         for (;;)
                                393                 :         {
 2630 tgl                       394 GIC       22149 :             resarr->lastidx &= mask;
 2630 tgl                       395 CBC       22149 :             if (resarr->itemsarr[resarr->lastidx] != resarr->invalidval)
                                396            8983 :                 break;
                                397           13166 :             resarr->lastidx++;
 2630 tgl                       398 ECB             :         }
                                399                 :     }
                                400                 : 
 2630 tgl                       401 GIC       92868 :     *value = resarr->itemsarr[resarr->lastidx];
 2630 tgl                       402 CBC       92868 :     return true;
 2630 tgl                       403 ECB             : }
                                404                 : 
                                405                 : /*
                                406                 :  * Trash a ResourceArray (we don't care about its state after this)
                                407                 :  */
                                408                 : static void
 2630 tgl                       409 GIC    13047411 : ResourceArrayFree(ResourceArray *resarr)
 2630 tgl                       410 ECB             : {
 2630 tgl                       411 GIC    13047411 :     if (resarr->itemsarr)
 2630 tgl                       412 CBC     3400021 :         pfree(resarr->itemsarr);
                                413        13047411 : }
 2630 tgl                       414 ECB             : 
                                415                 : 
                                416                 : /*****************************************************************************
                                417                 :  *    EXPORTED ROUTINES                                                      *
                                418                 :  *****************************************************************************/
                                419                 : 
                                420                 : 
                                421                 : /*
                                422                 :  * ResourceOwnerCreate
                                423                 :  *      Create an empty ResourceOwner.
                                424                 :  *
                                425                 :  * All ResourceOwner objects are kept in TopMemoryContext, since they should
                                426                 :  * only be freed explicitly.
                                427                 :  */
                                428                 : ResourceOwner
 6840 tgl                       429 GIC     1006059 : ResourceOwnerCreate(ResourceOwner parent, const char *name)
 6840 tgl                       430 ECB             : {
                                431                 :     ResourceOwner owner;
                                432                 : 
 6840 tgl                       433 GIC     1006059 :     owner = (ResourceOwner) MemoryContextAllocZero(TopMemoryContext,
 6385 bruce                     434 ECB             :                                                    sizeof(ResourceOwnerData));
 6840 tgl                       435 GIC     1006059 :     owner->name = name;
 6840 tgl                       436 ECB             : 
 6840 tgl                       437 GIC     1006059 :     if (parent)
 6840 tgl                       438 ECB             :     {
 6840 tgl                       439 GIC      516105 :         owner->parent = parent;
 6840 tgl                       440 CBC      516105 :         owner->nextchild = parent->firstchild;
                                441          516105 :         parent->firstchild = owner;
 6840 tgl                       442 ECB             :     }
                                443                 : 
 2630 tgl                       444 GIC     1006059 :     ResourceArrayInit(&(owner->bufferarr), BufferGetDatum(InvalidBuffer));
    4 andres                    445 GNC     1006059 :     ResourceArrayInit(&(owner->bufferioarr), BufferGetDatum(InvalidBuffer));
 2630 tgl                       446 CBC     1006059 :     ResourceArrayInit(&(owner->catrefarr), PointerGetDatum(NULL));
                                447         1006059 :     ResourceArrayInit(&(owner->catlistrefarr), PointerGetDatum(NULL));
                                448         1006059 :     ResourceArrayInit(&(owner->relrefarr), PointerGetDatum(NULL));
                                449         1006059 :     ResourceArrayInit(&(owner->planrefarr), PointerGetDatum(NULL));
                                450         1006059 :     ResourceArrayInit(&(owner->tupdescarr), PointerGetDatum(NULL));
                                451         1006059 :     ResourceArrayInit(&(owner->snapshotarr), PointerGetDatum(NULL));
                                452         1006059 :     ResourceArrayInit(&(owner->filearr), FileGetDatum(-1));
                                453         1006059 :     ResourceArrayInit(&(owner->dsmarr), PointerGetDatum(NULL));
 1845 andres                    454         1006059 :     ResourceArrayInit(&(owner->jitarr), PointerGetDatum(NULL));
  856 michael                   455         1006059 :     ResourceArrayInit(&(owner->cryptohasharr), PointerGetDatum(NULL));
  736                           456         1006059 :     ResourceArrayInit(&(owner->hmacarr), PointerGetDatum(NULL));
 2630 tgl                       457 ECB             : 
 6840 tgl                       458 CBC     1006059 :     return owner;
                                459                 : }
 6840 tgl                       460 ECB             : 
                                461                 : /*
                                462                 :  * ResourceOwnerRelease
                                463                 :  *      Release all resources owned by a ResourceOwner and its descendants,
                                464                 :  *      but don't delete the owner objects themselves.
                                465                 :  *
                                466                 :  * Note that this executes just one phase of release, and so typically
                                467                 :  * must be called three times.  We do it this way because (a) we want to
                                468                 :  * do all the recursion separately for each phase, thereby preserving
                                469                 :  * the needed order of operations; and (b) xact.c may have other operations
                                470                 :  * to do between the phases.
                                471                 :  *
                                472                 :  * phase: release phase to execute
                                473                 :  * isCommit: true for successful completion of a query or transaction,
                                474                 :  *          false for unsuccessful
                                475                 :  * isTopLevel: true if completing a main transaction, else false
                                476                 :  *
                                477                 :  * isCommit is passed because some modules may expect that their resources
                                478                 :  * were all released already if the transaction or portal finished normally.
                                479                 :  * If so it is reasonable to give a warning (NOT an error) should any
                                480                 :  * unreleased resources be present.  When isCommit is false, such warnings
                                481                 :  * are generally inappropriate.
                                482                 :  *
                                483                 :  * isTopLevel is passed when we are releasing TopTransactionResourceOwner
                                484                 :  * at completion of a main transaction.  This generally means that *all*
                                485                 :  * resources will be released, and so we can optimize things a bit.
                                486                 :  */
                                487                 : void
 6840 tgl                       488 GIC     2932668 : ResourceOwnerRelease(ResourceOwner owner,
                                489                 :                      ResourceReleasePhase phase,
 6840 tgl                       490 ECB             :                      bool isCommit,
                                491                 :                      bool isTopLevel)
                                492                 : {
                                493                 :     /* There's not currently any setup needed before recursing */
 2006 tgl                       494 GIC     2932668 :     ResourceOwnerReleaseInternal(owner, phase, isCommit, isTopLevel);
 6826                           495         2932668 : }
 6826 tgl                       496 ECB             : 
                                497                 : static void
 6826 tgl                       498 GIC     3018624 : ResourceOwnerReleaseInternal(ResourceOwner owner,
                                499                 :                              ResourceReleasePhase phase,
 6826 tgl                       500 ECB             :                              bool isCommit,
                                501                 :                              bool isTopLevel)
                                502                 : {
                                503                 :     ResourceOwner child;
                                504                 :     ResourceOwner save;
                                505                 :     ResourceReleaseCallbackItem *item;
                                506                 :     ResourceReleaseCallbackItem *next;
                                507                 :     Datum       foundres;
                                508                 : 
                                509                 :     /* Recurse to handle descendants */
 6840 tgl                       510 GIC     3104580 :     for (child = owner->firstchild; child != NULL; child = child->nextchild)
 6826                           511           85956 :         ResourceOwnerReleaseInternal(child, phase, isCommit, isTopLevel);
                                512                 : 
 6840 tgl                       513 ECB             :     /*
 6385 bruce                     514                 :      * Make CurrentResourceOwner point to me, so that ReleaseBuffer etc don't
                                515                 :      * get confused.
                                516                 :      */
 6840 tgl                       517 GIC     3018624 :     save = CurrentResourceOwner;
                                518         3018624 :     CurrentResourceOwner = owner;
                                519                 : 
 6840 tgl                       520 CBC     3018624 :     if (phase == RESOURCE_RELEASE_BEFORE_LOCKS)
 6840 tgl                       521 ECB             :     {
                                522                 :         /*
                                523                 :          * Abort failed buffer IO. AbortBufferIO()->TerminateBufferIO() calls
                                524                 :          * ResourceOwnerForgetBufferIOs(), so we just have to iterate till
                                525                 :          * there are none.
                                526                 :          *
                                527                 :          * Needs to be before we release buffer pins.
                                528                 :          *
                                529                 :          * During a commit, there shouldn't be any in-progress IO.
                                530                 :          */
    4 andres                    531 GNC     1006221 :         while (ResourceArrayGetAny(&(owner->bufferioarr), &foundres))
                                532                 :         {
                                533              13 :             Buffer      res = DatumGetBuffer(foundres);
                                534                 : 
                                535              13 :             if (isCommit)
    4 andres                    536 UNC           0 :                 elog(PANIC, "lost track of buffer IO on buffer %u", res);
    4 andres                    537 GNC          13 :             AbortBufferIO(res);
                                538                 :         }
                                539                 : 
                                540                 :         /*
 6385 bruce                     541 ECB             :          * Release buffer pins.  Note that ReleaseBuffer will remove the
                                542                 :          * buffer entry from our array, so we just have to iterate till there
                                543                 :          * are none.
                                544                 :          *
                                545                 :          * During a commit, there shouldn't be any remaining pins --- that
                                546                 :          * would indicate failure to clean up the executor correctly --- so
                                547                 :          * issue warnings.  In the abort case, just clean up quietly.
                                548                 :          */
 2630 tgl                       549 GIC     1009873 :         while (ResourceArrayGetAny(&(owner->bufferarr), &foundres))
                                550                 :         {
                                551            3665 :             Buffer      res = DatumGetBuffer(foundres);
 2630 tgl                       552 ECB             : 
 6749 tgl                       553 GIC        3665 :             if (isCommit)
 2630 tgl                       554 LBC           0 :                 PrintBufferLeakWarning(res);
 2630 tgl                       555 GIC        3665 :             ReleaseBuffer(res);
 6840 tgl                       556 ECB             :         }
 6749 tgl                       557 EUB             : 
 2630 tgl                       558 ECB             :         /* Ditto for relcache references */
 2630 tgl                       559 GIC     1022070 :         while (ResourceArrayGetAny(&(owner->relrefarr), &foundres))
                                560                 :         {
                                561           15862 :             Relation    res = (Relation) DatumGetPointer(foundres);
                                562                 : 
 6453                           563           15862 :             if (isCommit)
 2630 tgl                       564 UIC           0 :                 PrintRelCacheLeakWarning(res);
 2630 tgl                       565 GIC       15862 :             RelationClose(res);
                                566                 :         }
                                567                 : 
                                568                 :         /* Ditto for dynamic shared memory segments */
                                569         1006208 :         while (ResourceArrayGetAny(&(owner->dsmarr), &foundres))
 3469 rhaas                     570 ECB             :         {
 2630 tgl                       571 UIC           0 :             dsm_segment *res = (dsm_segment *) DatumGetPointer(foundres);
 2630 tgl                       572 ECB             : 
 3469 rhaas                     573 UIC           0 :             if (isCommit)
 2630 tgl                       574 LBC           0 :                 PrintDSMLeakWarning(res);
 2630 tgl                       575 UBC           0 :             dsm_detach(res);
 3469 rhaas                     576 ECB             :         }
                                577                 : 
                                578                 :         /* Ditto for JIT contexts */
 1845 andres                    579 GIC     1006216 :         while (ResourceArrayGetAny(&(owner->jitarr), &foundres))
 1845 andres                    580 ECB             :         {
  224 peter                     581 GNC           8 :             JitContext *context = (JitContext *) DatumGetPointer(foundres);
 1845 andres                    582 ECB             : 
 1845 andres                    583 GIC           8 :             jit_release_context(context);
 1845 andres                    584 ECB             :         }
  856 michael                   585 EUB             : 
  856 michael                   586 ECB             :         /* Ditto for cryptohash contexts */
  856 michael                   587 GIC     1006212 :         while (ResourceArrayGetAny(&(owner->cryptohasharr), &foundres))
                                588                 :         {
                                589                 :             pg_cryptohash_ctx *context =
  224 peter                     590 GNC           4 :             (pg_cryptohash_ctx *) DatumGetPointer(foundres);
                                591                 : 
  856 michael                   592 GBC           4 :             if (isCommit)
  856 michael                   593 UIC           0 :                 PrintCryptoHashLeakWarning(foundres);
  856 michael                   594 GBC           4 :             pg_cryptohash_free(context);
  856 michael                   595 EUB             :         }
  736                           596                 : 
                                597                 :         /* Ditto for HMAC contexts */
  736 michael                   598 GIC     1006208 :         while (ResourceArrayGetAny(&(owner->hmacarr), &foundres))
                                599                 :         {
  224 peter                     600 UNC           0 :             pg_hmac_ctx *context = (pg_hmac_ctx *) DatumGetPointer(foundres);
                                601                 : 
  736 michael                   602 LBC           0 :             if (isCommit)
  736 michael                   603 UIC           0 :                 PrintHMACLeakWarning(foundres);
  736 michael                   604 LBC           0 :             pg_hmac_free(context);
                                605                 :         }
                                606                 :     }
 6840 tgl                       607 GIC     2012416 :     else if (phase == RESOURCE_RELEASE_LOCKS)
 6840 tgl                       608 ECB             :     {
 6840 tgl                       609 GIC     1006208 :         if (isTopLevel)
                                610                 :         {
 6840 tgl                       611 ECB             :             /*
                                612                 :              * For a top-level xact we are going to release all locks (or at
 6385 bruce                     613                 :              * least all non-session locks), so just do a single lmgr call at
 6385 bruce                     614 EUB             :              * the top of the recursion.
 6840 tgl                       615 ECB             :              */
 6840 tgl                       616 GIC      518632 :             if (owner == TopTransactionResourceOwner)
                                617                 :             {
                                618          486958 :                 ProcReleaseLocks(isCommit);
 1486 tmunro                    619 CBC      486958 :                 ReleasePredicateLocks(isCommit, false);
                                620                 :             }
 6840 tgl                       621 EUB             :         }
                                622                 :         else
                                623                 :         {
                                624                 :             /*
 6799                           625                 :              * Release locks retail.  Note that if we are committing a
                                626                 :              * subtransaction, we do NOT release its locks yet, but transfer
                                627                 :              * them to the parent.
 6840 tgl                       628 ECB             :              */
                                629                 :             LOCALLOCK **locks;
 3944 heikki.linnakangas        630                 :             int         nlocks;
                                631                 : 
 6801 tgl                       632 GIC      487576 :             Assert(owner->parent != NULL);
                                633                 : 
                                634                 :             /*
                                635                 :              * Pass the list of locks owned by this resource owner to the lock
                                636                 :              * manager, unless it has overflowed.
 3944 heikki.linnakangas        637 ECB             :              */
 3944 heikki.linnakangas        638 GIC      487576 :             if (owner->nlocks > MAX_RESOWNER_LOCKS)
 3944 heikki.linnakangas        639 ECB             :             {
 3944 heikki.linnakangas        640 CBC        3495 :                 locks = NULL;
 3944 heikki.linnakangas        641 GIC        3495 :                 nlocks = 0;
                                642                 :             }
                                643                 :             else
                                644                 :             {
                                645          484081 :                 locks = owner->locks;
                                646          484081 :                 nlocks = owner->nlocks;
                                647                 :             }
                                648                 : 
 6799 tgl                       649          487576 :             if (isCommit)
 3944 heikki.linnakangas        650          482967 :                 LockReassignCurrentOwner(locks, nlocks);
                                651                 :             else
                                652            4609 :                 LockReleaseCurrentOwner(locks, nlocks);
 6840 tgl                       653 ECB             :         }
                                654                 :     }
 6840 tgl                       655 GIC     1006208 :     else if (phase == RESOURCE_RELEASE_AFTER_LOCKS)
                                656                 :     {
                                657                 :         /*
                                658                 :          * Release catcache references.  Note that ReleaseCatCache will remove
 2630 tgl                       659 ECB             :          * the catref entry from our array, so we just have to iterate till
                                660                 :          * there are none.
 6453                           661                 :          *
 2630                           662                 :          * As with buffer pins, warn if any are left at commit time.
                                663                 :          */
 2630 tgl                       664 GIC     1010879 :         while (ResourceArrayGetAny(&(owner->catrefarr), &foundres))
                                665                 :         {
 2630 tgl                       666 CBC        4671 :             HeapTuple   res = (HeapTuple) DatumGetPointer(foundres);
 2630 tgl                       667 ECB             : 
 6453 tgl                       668 GIC        4671 :             if (isCommit)
 2630 tgl                       669 UIC           0 :                 PrintCatCacheLeakWarning(res);
 2630 tgl                       670 CBC        4671 :             ReleaseCatCache(res);
 6840 tgl                       671 ECB             :         }
                                672                 : 
 6141                           673                 :         /* Ditto for catcache lists */
 2630 tgl                       674 GIC     1006226 :         while (ResourceArrayGetAny(&(owner->catlistrefarr), &foundres))
                                675                 :         {
 2630 tgl                       676 CBC          18 :             CatCList   *res = (CatCList *) DatumGetPointer(foundres);
                                677                 : 
 6453 tgl                       678 GIC          18 :             if (isCommit)
 2630 tgl                       679 UIC           0 :                 PrintCatCacheListLeakWarning(res);
 2630 tgl                       680 GIC          18 :             ReleaseCatCacheList(res);
                                681                 :         }
                                682                 : 
                                683                 :         /* Ditto for plancache references */
                                684         1011274 :         while (ResourceArrayGetAny(&(owner->planrefarr), &foundres))
 5871 tgl                       685 ECB             :         {
 2630 tgl                       686 GIC        5066 :             CachedPlan *res = (CachedPlan *) DatumGetPointer(foundres);
 2630 tgl                       687 ECB             : 
 5871 tgl                       688 GIC        5066 :             if (isCommit)
 2630 tgl                       689 LBC           0 :                 PrintPlanCacheLeakWarning(res);
  804 tgl                       690 GBC        5066 :             ReleaseCachedPlan(res, owner);
 5871 tgl                       691 ECB             :         }
                                692                 : 
                                693                 :         /* Ditto for tupdesc references */
 2630 tgl                       694 GIC     1011717 :         while (ResourceArrayGetAny(&(owner->tupdescarr), &foundres))
 6141 tgl                       695 ECB             :         {
 2630 tgl                       696 GIC        5509 :             TupleDesc   res = (TupleDesc) DatumGetPointer(foundres);
 2630 tgl                       697 ECB             : 
 6141 tgl                       698 GIC        5509 :             if (isCommit)
 2630 tgl                       699 LBC           0 :                 PrintTupleDescLeakWarning(res);
 2630 tgl                       700 GBC        5509 :             DecrTupleDescRefCount(res);
 6141 tgl                       701 ECB             :         }
                                702                 : 
                                703                 :         /* Ditto for snapshot references */
 2630 tgl                       704 GIC     1031379 :         while (ResourceArrayGetAny(&(owner->snapshotarr), &foundres))
 5248 alvherre                  705 ECB             :         {
 2630 tgl                       706 GIC       25171 :             Snapshot    res = (Snapshot) DatumGetPointer(foundres);
 2630 tgl                       707 ECB             : 
 5248 alvherre                  708 GIC       25171 :             if (isCommit)
 2630 tgl                       709 LBC           0 :                 PrintSnapshotLeakWarning(res);
 2630 tgl                       710 GBC       25171 :             UnregisterSnapshot(res);
 5248 alvherre                  711 ECB             :         }
                                712                 : 
                                713                 :         /* Ditto for temporary files */
 2630 tgl                       714 GIC     1006212 :         while (ResourceArrayGetAny(&(owner->filearr), &foundres))
 4875 heikki.linnakangas        715 ECB             :         {
 2630 tgl                       716 GIC           4 :             File        res = DatumGetFile(foundres);
 2630 tgl                       717 ECB             : 
 4875 heikki.linnakangas        718 GIC           4 :             if (isCommit)
 2630 tgl                       719 LBC           0 :                 PrintFileLeakWarning(res);
 2630 tgl                       720 GBC           4 :             FileClose(res);
 4875 heikki.linnakangas        721 ECB             :         }
                                722                 :     }
                                723                 : 
                                724                 :     /* Let add-on modules get a chance too */
  193 tgl                       725 GNC     3020262 :     for (item = ResourceRelease_callbacks; item; item = next)
                                726                 :     {
                                727                 :         /* allow callbacks to unregister themselves when called */
                                728            1638 :         next = item->next;
 2040 peter_e                   729 GIC        1638 :         item->callback(phase, isCommit, isTopLevel, item->arg);
                                730                 :     }
 6840 tgl                       731 ECB             : 
 6840 tgl                       732 GIC     3018624 :     CurrentResourceOwner = save;
 6840 tgl                       733 CBC     3018624 : }
 6840 tgl                       734 EUB             : 
 1109 tgl                       735 ECB             : /*
                                736                 :  * ResourceOwnerReleaseAllPlanCacheRefs
                                737                 :  *      Release the plancache references (only) held by this owner.
                                738                 :  *
                                739                 :  * We might eventually add similar functions for other resource types,
                                740                 :  * but for now, only this is needed.
                                741                 :  */
                                742                 : void
 1109 tgl                       743 CBC        7302 : ResourceOwnerReleaseAllPlanCacheRefs(ResourceOwner owner)
 1109 tgl                       744 EUB             : {
 1109 tgl                       745 ECB             :     Datum       foundres;
                                746                 : 
 1109 tgl                       747 GIC       40179 :     while (ResourceArrayGetAny(&(owner->planrefarr), &foundres))
                                748                 :     {
                                749           32877 :         CachedPlan *res = (CachedPlan *) DatumGetPointer(foundres);
 1109 tgl                       750 ECB             : 
  804 tgl                       751 GIC       32877 :         ReleaseCachedPlan(res, owner);
                                752                 :     }
 1109 tgl                       753 CBC        7302 : }
 1109 tgl                       754 ECB             : 
                                755                 : /*
                                756                 :  * ResourceOwnerDelete
 6840                           757                 :  *      Delete an owner object and its descendants.
                                758                 :  *
                                759                 :  * The caller must have already released all resources in the object tree.
                                760                 :  */
                                761                 : void
 6840 tgl                       762 GIC     1003647 : ResourceOwnerDelete(ResourceOwner owner)
                                763                 : {
                                764                 :     /* We had better not be deleting CurrentResourceOwner ... */
                                765         1003647 :     Assert(owner != CurrentResourceOwner);
                                766                 : 
                                767                 :     /* And it better not own any resources, either */
 2630 tgl                       768 CBC     1003647 :     Assert(owner->bufferarr.nitems == 0);
    4 andres                    769 GNC     1003647 :     Assert(owner->bufferioarr.nitems == 0);
 2630 tgl                       770 GIC     1003647 :     Assert(owner->catrefarr.nitems == 0);
                                771         1003647 :     Assert(owner->catlistrefarr.nitems == 0);
                                772         1003647 :     Assert(owner->relrefarr.nitems == 0);
 2630 tgl                       773 CBC     1003647 :     Assert(owner->planrefarr.nitems == 0);
 2630 tgl                       774 GIC     1003647 :     Assert(owner->tupdescarr.nitems == 0);
 2630 tgl                       775 CBC     1003647 :     Assert(owner->snapshotarr.nitems == 0);
 2630 tgl                       776 GIC     1003647 :     Assert(owner->filearr.nitems == 0);
 2630 tgl                       777 CBC     1003647 :     Assert(owner->dsmarr.nitems == 0);
 1845 andres                    778 GIC     1003647 :     Assert(owner->jitarr.nitems == 0);
  856 michael                   779 CBC     1003647 :     Assert(owner->cryptohasharr.nitems == 0);
  736 michael                   780 GIC     1003647 :     Assert(owner->hmacarr.nitems == 0);
 3944 heikki.linnakangas        781         1003647 :     Assert(owner->nlocks == 0 || owner->nlocks == MAX_RESOWNER_LOCKS + 1);
                                782                 : 
                                783                 :     /*
                                784                 :      * Delete children.  The recursive call will delink the child from me, so
                                785                 :      * just iterate as long as there is a child.
                                786                 :      */
 6840 tgl                       787         1032302 :     while (owner->firstchild != NULL)
 6840 tgl                       788 CBC       28655 :         ResourceOwnerDelete(owner->firstchild);
                                789                 : 
                                790                 :     /*
 6797 bruce                     791 ECB             :      * We delink the owner from its parent before deleting it, so that if
                                792                 :      * there's an error we won't have deleted/busted owners still attached to
                                793                 :      * the owner tree.  Better a leak than a crash.
 6840 tgl                       794                 :      */
 6840 tgl                       795 CBC     1003647 :     ResourceOwnerNewParent(owner, NULL);
 6840 tgl                       796 ECB             : 
                                797                 :     /* And free the object. */
 2630 tgl                       798 CBC     1003647 :     ResourceArrayFree(&(owner->bufferarr));
    4 andres                    799 GNC     1003647 :     ResourceArrayFree(&(owner->bufferioarr));
 2630 tgl                       800 CBC     1003647 :     ResourceArrayFree(&(owner->catrefarr));
                                801         1003647 :     ResourceArrayFree(&(owner->catlistrefarr));
                                802         1003647 :     ResourceArrayFree(&(owner->relrefarr));
                                803         1003647 :     ResourceArrayFree(&(owner->planrefarr));
                                804         1003647 :     ResourceArrayFree(&(owner->tupdescarr));
                                805         1003647 :     ResourceArrayFree(&(owner->snapshotarr));
                                806         1003647 :     ResourceArrayFree(&(owner->filearr));
                                807         1003647 :     ResourceArrayFree(&(owner->dsmarr));
 1845 andres                    808         1003647 :     ResourceArrayFree(&(owner->jitarr));
  856 michael                   809 GIC     1003647 :     ResourceArrayFree(&(owner->cryptohasharr));
  736                           810         1003647 :     ResourceArrayFree(&(owner->hmacarr));
                                811                 : 
 6840 tgl                       812         1003647 :     pfree(owner);
                                813         1003647 : }
 6840 tgl                       814 ECB             : 
 6799                           815                 : /*
                                816                 :  * Fetch parent of a ResourceOwner (returns NULL if top-level owner)
                                817                 :  */
                                818                 : ResourceOwner
 6799 tgl                       819 GIC      482967 : ResourceOwnerGetParent(ResourceOwner owner)
                                820                 : {
                                821          482967 :     return owner->parent;
 6799 tgl                       822 ECB             : }
                                823                 : 
                                824                 : /*
 6840                           825                 :  * Reassign a ResourceOwner to have a new parent
                                826                 :  */
                                827                 : void
 6840 tgl                       828 CBC     1003682 : ResourceOwnerNewParent(ResourceOwner owner,
 6840 tgl                       829 ECB             :                        ResourceOwner newparent)
                                830                 : {
 6840 tgl                       831 CBC     1003682 :     ResourceOwner oldparent = owner->parent;
 6840 tgl                       832 ECB             : 
 6840 tgl                       833 CBC     1003682 :     if (oldparent)
 6840 tgl                       834 ECB             :     {
 6840 tgl                       835 CBC      516140 :         if (owner == oldparent->firstchild)
                                836          508911 :             oldparent->firstchild = owner->nextchild;
 6840 tgl                       837 ECB             :         else
                                838                 :         {
                                839                 :             ResourceOwner child;
                                840                 : 
 6840 tgl                       841 GIC        8148 :             for (child = oldparent->firstchild; child; child = child->nextchild)
                                842                 :             {
                                843            8148 :                 if (owner == child->nextchild)
                                844                 :                 {
                                845            7229 :                     child->nextchild = owner->nextchild;
 6840 tgl                       846 CBC        7229 :                     break;
                                847                 :                 }
 6840 tgl                       848 ECB             :             }
                                849                 :         }
                                850                 :     }
                                851                 : 
 6840 tgl                       852 GIC     1003682 :     if (newparent)
                                853                 :     {
                                854              35 :         Assert(owner != newparent);
 6840 tgl                       855 CBC          35 :         owner->parent = newparent;
 6840 tgl                       856 GIC          35 :         owner->nextchild = newparent->firstchild;
                                857              35 :         newparent->firstchild = owner;
 6840 tgl                       858 ECB             :     }
                                859                 :     else
                                860                 :     {
 6840 tgl                       861 GIC     1003647 :         owner->parent = NULL;
 6840 tgl                       862 CBC     1003647 :         owner->nextchild = NULL;
 6840 tgl                       863 ECB             :     }
 6840 tgl                       864 GIC     1003682 : }
                                865                 : 
                                866                 : /*
                                867                 :  * Register or deregister callback functions for resource cleanup
 6840 tgl                       868 ECB             :  *
                                869                 :  * These functions are intended for use by dynamically loaded modules.
                                870                 :  * For built-in modules we generally just hardwire the appropriate calls.
                                871                 :  *
                                872                 :  * Note that the callback occurs post-commit or post-abort, so the callback
                                873                 :  * functions can only do noncritical cleanup.
                                874                 :  */
                                875                 : void
 6840 tgl                       876 GIC          23 : RegisterResourceReleaseCallback(ResourceReleaseCallback callback, void *arg)
                                877                 : {
                                878                 :     ResourceReleaseCallbackItem *item;
 6840 tgl                       879 ECB             : 
                                880                 :     item = (ResourceReleaseCallbackItem *)
 6840 tgl                       881 CBC          23 :         MemoryContextAlloc(TopMemoryContext,
 6840 tgl                       882 ECB             :                            sizeof(ResourceReleaseCallbackItem));
 6840 tgl                       883 CBC          23 :     item->callback = callback;
                                884              23 :     item->arg = arg;
 6840 tgl                       885 GIC          23 :     item->next = ResourceRelease_callbacks;
                                886              23 :     ResourceRelease_callbacks = item;
                                887              23 : }
 6840 tgl                       888 ECB             : 
                                889                 : void
 6840 tgl                       890 UIC           0 : UnregisterResourceReleaseCallback(ResourceReleaseCallback callback, void *arg)
 6840 tgl                       891 ECB             : {
                                892                 :     ResourceReleaseCallbackItem *item;
                                893                 :     ResourceReleaseCallbackItem *prev;
                                894                 : 
 6840 tgl                       895 UIC           0 :     prev = NULL;
                                896               0 :     for (item = ResourceRelease_callbacks; item; prev = item, item = item->next)
                                897                 :     {
                                898               0 :         if (item->callback == callback && item->arg == arg)
                                899                 :         {
                                900               0 :             if (prev)
                                901               0 :                 prev->next = item->next;
                                902                 :             else
 6840 tgl                       903 LBC           0 :                 ResourceRelease_callbacks = item->next;
 6840 tgl                       904 UIC           0 :             pfree(item);
                                905               0 :             break;
                                906                 :         }
                                907                 :     }
 6840 tgl                       908 LBC           0 : }
                                909                 : 
 1726 tgl                       910 ECB             : /*
                                911                 :  * Establish an AuxProcessResourceOwner for the current process.
                                912                 :  */
                                913                 : void
 1726 tgl                       914 CBC        2407 : CreateAuxProcessResourceOwner(void)
                                915                 : {
 1726 tgl                       916 GIC        2407 :     Assert(AuxProcessResourceOwner == NULL);
 1726 tgl                       917 GBC        2407 :     Assert(CurrentResourceOwner == NULL);
 1726 tgl                       918 GIC        2407 :     AuxProcessResourceOwner = ResourceOwnerCreate(NULL, "AuxiliaryProcess");
                                919            2407 :     CurrentResourceOwner = AuxProcessResourceOwner;
                                920                 : 
                                921                 :     /*
 1726 tgl                       922 EUB             :      * Register a shmem-exit callback for cleanup of aux-process resource
                                923                 :      * owner.  (This needs to run after, e.g., ShutdownXLOG.)
                                924                 :      */
 1726 tgl                       925 GBC        2407 :     on_shmem_exit(ReleaseAuxProcessResourcesCallback, 0);
 1726 tgl                       926 GIC        2407 : }
 1726 tgl                       927 EUB             : 
                                928                 : /*
                                929                 :  * Convenience routine to release all resources tracked in
                                930                 :  * AuxProcessResourceOwner (but that resowner is not destroyed here).
                                931                 :  * Warn about leaked resources if isCommit is true.
                                932                 :  */
                                933                 : void
 1726 tgl                       934 GIC        3026 : ReleaseAuxProcessResources(bool isCommit)
 1726 tgl                       935 EUB             : {
                                936                 :     /*
                                937                 :      * At this writing, the only thing that could actually get released is
                                938                 :      * buffer pins; but we may as well do the full release protocol.
                                939                 :      */
 1726 tgl                       940 GIC        3026 :     ResourceOwnerRelease(AuxProcessResourceOwner,
 1726 tgl                       941 ECB             :                          RESOURCE_RELEASE_BEFORE_LOCKS,
                                942                 :                          isCommit, true);
 1726 tgl                       943 CBC        3026 :     ResourceOwnerRelease(AuxProcessResourceOwner,
 1726 tgl                       944 ECB             :                          RESOURCE_RELEASE_LOCKS,
                                945                 :                          isCommit, true);
 1726 tgl                       946 CBC        3026 :     ResourceOwnerRelease(AuxProcessResourceOwner,
                                947                 :                          RESOURCE_RELEASE_AFTER_LOCKS,
                                948                 :                          isCommit, true);
 1726 tgl                       949 GIC        3026 : }
                                950                 : 
                                951                 : /*
 1726 tgl                       952 ECB             :  * Shmem-exit callback for the same.
                                953                 :  * Warn about leaked resources if process exit code is zero (ie normal).
                                954                 :  */
                                955                 : static void
 1726 tgl                       956 GIC        2407 : ReleaseAuxProcessResourcesCallback(int code, Datum arg)
                                957                 : {
                                958            2407 :     bool        isCommit = (code == 0);
                                959                 : 
                                960            2407 :     ReleaseAuxProcessResources(isCommit);
 1726 tgl                       961 CBC        2407 : }
                                962                 : 
                                963                 : 
                                964                 : /*
                                965                 :  * Make sure there is room for at least one more entry in a ResourceOwner's
                                966                 :  * buffer array.
 6840 tgl                       967 ECB             :  *
                                968                 :  * This is separate from actually inserting an entry because if we run out
                                969                 :  * of memory, it's critical to do so *before* acquiring the resource.
                                970                 :  */
                                971                 : void
 6840 tgl                       972 GIC    84925049 : ResourceOwnerEnlargeBuffers(ResourceOwner owner)
 6840 tgl                       973 ECB             : {
                                974                 :     /* We used to allow pinning buffers without a resowner, but no more */
 1726 tgl                       975 GIC    84925049 :     Assert(owner != NULL);
 2630 tgl                       976 CBC    84925049 :     ResourceArrayEnlarge(&(owner->bufferarr));
 6840 tgl                       977 GIC    84925049 : }
                                978                 : 
                                979                 : /*
                                980                 :  * Remember that a buffer pin is owned by a ResourceOwner
                                981                 :  *
                                982                 :  * Caller must have previously done ResourceOwnerEnlargeBuffers()
 6840 tgl                       983 ECB             :  */
                                984                 : void
 6840 tgl                       985 CBC    83570573 : ResourceOwnerRememberBuffer(ResourceOwner owner, Buffer buffer)
                                986                 : {
 2630                           987        83570573 :     ResourceArrayAdd(&(owner->bufferarr), BufferGetDatum(buffer));
 6840                           988        83570573 : }
                                989                 : 
                                990                 : /*
                                991                 :  * Forget that a buffer pin is owned by a ResourceOwner
                                992                 :  */
                                993                 : void
 6840 tgl                       994 GIC    83570573 : ResourceOwnerForgetBuffer(ResourceOwner owner, Buffer buffer)
                                995                 : {
 2630                           996        83570573 :     if (!ResourceArrayRemove(&(owner->bufferarr), BufferGetDatum(buffer)))
 6840 tgl                       997 UIC           0 :         elog(ERROR, "buffer %d is not owned by resource owner %s",
                                998                 :              buffer, owner->name);
 6840 tgl                       999 CBC    83570573 : }
                               1000                 : 
                               1001                 : 
                               1002                 : /*
                               1003                 :  * Make sure there is room for at least one more entry in a ResourceOwner's
                               1004                 :  * buffer array.
                               1005                 :  *
                               1006                 :  * This is separate from actually inserting an entry because if we run out
                               1007                 :  * of memory, it's critical to do so *before* acquiring the resource.
                               1008                 :  */
                               1009                 : void
    4 andres                   1010 GNC     2601190 : ResourceOwnerEnlargeBufferIOs(ResourceOwner owner)
                               1011                 : {
                               1012                 :     /* We used to allow pinning buffers without a resowner, but no more */
                               1013         2601190 :     Assert(owner != NULL);
                               1014         2601190 :     ResourceArrayEnlarge(&(owner->bufferioarr));
                               1015         2601190 : }
                               1016                 : 
                               1017                 : /*
                               1018                 :  * Remember that a buffer IO is owned by a ResourceOwner
                               1019                 :  *
                               1020                 :  * Caller must have previously done ResourceOwnerEnlargeBufferIOs()
                               1021                 :  */
                               1022                 : void
                               1023         2599422 : ResourceOwnerRememberBufferIO(ResourceOwner owner, Buffer buffer)
                               1024                 : {
                               1025         2599422 :     ResourceArrayAdd(&(owner->bufferioarr), BufferGetDatum(buffer));
                               1026         2599422 : }
                               1027                 : 
                               1028                 : /*
                               1029                 :  * Forget that a buffer IO is owned by a ResourceOwner
                               1030                 :  */
                               1031                 : void
                               1032         2599422 : ResourceOwnerForgetBufferIO(ResourceOwner owner, Buffer buffer)
                               1033                 : {
                               1034         2599422 :     if (!ResourceArrayRemove(&(owner->bufferioarr), BufferGetDatum(buffer)))
    4 andres                   1035 UNC           0 :         elog(PANIC, "buffer IO %d is not owned by resource owner %s",
                               1036                 :              buffer, owner->name);
    4 andres                   1037 GNC     2599422 : }
                               1038                 : 
                               1039                 : /*
 3944 heikki.linnakangas       1040 ECB             :  * Remember that a Local Lock is owned by a ResourceOwner
                               1041                 :  *
                               1042                 :  * This is different from the other Remember functions in that the list of
                               1043                 :  * locks is only a lossy cache. It can hold up to MAX_RESOWNER_LOCKS entries,
                               1044                 :  * and when it overflows, we stop tracking locks. The point of only remembering
                               1045                 :  * only up to MAX_RESOWNER_LOCKS entries is that if a lot of locks are held,
                               1046                 :  * ResourceOwnerForgetLock doesn't need to scan through a large array to find
                               1047                 :  * the entry.
                               1048                 :  */
                               1049                 : void
 3602 bruce                    1050 CBC    27048592 : ResourceOwnerRememberLock(ResourceOwner owner, LOCALLOCK *locallock)
                               1051                 : {
 2630 tgl                      1052        27048592 :     Assert(locallock != NULL);
 2630 tgl                      1053 ECB             : 
 3944 heikki.linnakangas       1054 GIC    27048592 :     if (owner->nlocks > MAX_RESOWNER_LOCKS)
 3602 bruce                    1055         2034678 :         return;                 /* we have already overflowed */
                               1056                 : 
 3944 heikki.linnakangas       1057        25013914 :     if (owner->nlocks < MAX_RESOWNER_LOCKS)
                               1058        25005006 :         owner->locks[owner->nlocks] = locallock;
 3944 heikki.linnakangas       1059 ECB             :     else
                               1060                 :     {
                               1061                 :         /* overflowed */
 3944 heikki.linnakangas       1062 EUB             :     }
 3944 heikki.linnakangas       1063 GIC    25013914 :     owner->nlocks++;
 3944 heikki.linnakangas       1064 ECB             : }
                               1065                 : 
                               1066                 : /*
                               1067                 :  * Forget that a Local Lock is owned by a ResourceOwner
                               1068                 :  */
                               1069                 : void
 3944 heikki.linnakangas       1070 GIC    27048592 : ResourceOwnerForgetLock(ResourceOwner owner, LOCALLOCK *locallock)
                               1071                 : {
                               1072                 :     int         i;
                               1073                 : 
                               1074        27048592 :     if (owner->nlocks > MAX_RESOWNER_LOCKS)
 3602 bruce                    1075 CBC     2177206 :         return;                 /* we have overflowed */
                               1076                 : 
 3944 heikki.linnakangas       1077 GIC    24871386 :     Assert(owner->nlocks > 0);
 3944 heikki.linnakangas       1078 CBC    28514759 :     for (i = owner->nlocks - 1; i >= 0; i--)
 3944 heikki.linnakangas       1079 ECB             :     {
 3944 heikki.linnakangas       1080 CBC    28514759 :         if (locallock == owner->locks[i])
                               1081                 :         {
 3944 heikki.linnakangas       1082 GIC    24871386 :             owner->locks[i] = owner->locks[owner->nlocks - 1];
                               1083        24871386 :             owner->nlocks--;
                               1084        24871386 :             return;
                               1085                 :         }
                               1086                 :     }
 3944 heikki.linnakangas       1087 UIC           0 :     elog(ERROR, "lock reference %p is not owned by resource owner %s",
 3944 heikki.linnakangas       1088 ECB             :          locallock, owner->name);
                               1089                 : }
                               1090                 : 
 6840 tgl                      1091                 : /*
                               1092                 :  * Make sure there is room for at least one more entry in a ResourceOwner's
                               1093                 :  * catcache reference array.
                               1094                 :  *
                               1095                 :  * This is separate from actually inserting an entry because if we run out
                               1096                 :  * of memory, it's critical to do so *before* acquiring the resource.
                               1097                 :  */
                               1098                 : void
 6840 tgl                      1099 CBC    48196159 : ResourceOwnerEnlargeCatCacheRefs(ResourceOwner owner)
 6840 tgl                      1100 EUB             : {
 2630 tgl                      1101 GIC    48196159 :     ResourceArrayEnlarge(&(owner->catrefarr));
 6840 tgl                      1102 CBC    48196159 : }
                               1103                 : 
                               1104                 : /*
                               1105                 :  * Remember that a catcache reference is owned by a ResourceOwner
                               1106                 :  *
                               1107                 :  * Caller must have previously done ResourceOwnerEnlargeCatCacheRefs()
                               1108                 :  */
                               1109                 : void
 6840 tgl                      1110 GIC    48196159 : ResourceOwnerRememberCatCacheRef(ResourceOwner owner, HeapTuple tuple)
                               1111                 : {
 2630                          1112        48196159 :     ResourceArrayAdd(&(owner->catrefarr), PointerGetDatum(tuple));
 6840                          1113        48196159 : }
                               1114                 : 
 6840 tgl                      1115 ECB             : /*
                               1116                 :  * Forget that a catcache reference is owned by a ResourceOwner
                               1117                 :  */
                               1118                 : void
 6840 tgl                      1119 CBC    48196159 : ResourceOwnerForgetCatCacheRef(ResourceOwner owner, HeapTuple tuple)
 6840 tgl                      1120 ECB             : {
 2630 tgl                      1121 GIC    48196159 :     if (!ResourceArrayRemove(&(owner->catrefarr), PointerGetDatum(tuple)))
 2630 tgl                      1122 LBC           0 :         elog(ERROR, "catcache reference %p is not owned by resource owner %s",
 2630 tgl                      1123 ECB             :              tuple, owner->name);
 6840 tgl                      1124 GIC    48196159 : }
                               1125                 : 
                               1126                 : /*
                               1127                 :  * Make sure there is room for at least one more entry in a ResourceOwner's
 6840 tgl                      1128 ECB             :  * catcache-list reference array.
                               1129                 :  *
                               1130                 :  * This is separate from actually inserting an entry because if we run out
                               1131                 :  * of memory, it's critical to do so *before* acquiring the resource.
                               1132                 :  */
                               1133                 : void
 6840 tgl                      1134 GIC     1600190 : ResourceOwnerEnlargeCatCacheListRefs(ResourceOwner owner)
 6840 tgl                      1135 ECB             : {
 2630 tgl                      1136 GIC     1600190 :     ResourceArrayEnlarge(&(owner->catlistrefarr));
 6840                          1137         1600190 : }
                               1138                 : 
 6840 tgl                      1139 ECB             : /*
                               1140                 :  * Remember that a catcache-list reference is owned by a ResourceOwner
                               1141                 :  *
                               1142                 :  * Caller must have previously done ResourceOwnerEnlargeCatCacheListRefs()
                               1143                 :  */
                               1144                 : void
 6840 tgl                      1145 CBC     1600190 : ResourceOwnerRememberCatCacheListRef(ResourceOwner owner, CatCList *list)
                               1146                 : {
 2630                          1147         1600190 :     ResourceArrayAdd(&(owner->catlistrefarr), PointerGetDatum(list));
 6840                          1148         1600190 : }
 6840 tgl                      1149 ECB             : 
                               1150                 : /*
                               1151                 :  * Forget that a catcache-list reference is owned by a ResourceOwner
 6840 tgl                      1152 EUB             :  */
                               1153                 : void
 6840 tgl                      1154 GIC     1600190 : ResourceOwnerForgetCatCacheListRef(ResourceOwner owner, CatCList *list)
                               1155                 : {
 2630                          1156         1600190 :     if (!ResourceArrayRemove(&(owner->catlistrefarr), PointerGetDatum(list)))
 2630 tgl                      1157 UIC           0 :         elog(ERROR, "catcache list reference %p is not owned by resource owner %s",
                               1158                 :              list, owner->name);
 6840 tgl                      1159 GIC     1600190 : }
                               1160                 : 
                               1161                 : /*
                               1162                 :  * Make sure there is room for at least one more entry in a ResourceOwner's
                               1163                 :  * relcache reference array.
 6840 tgl                      1164 ECB             :  *
                               1165                 :  * This is separate from actually inserting an entry because if we run out
                               1166                 :  * of memory, it's critical to do so *before* acquiring the resource.
                               1167                 :  */
                               1168                 : void
 6840 tgl                      1169 GIC    40884389 : ResourceOwnerEnlargeRelationRefs(ResourceOwner owner)
                               1170                 : {
 2630                          1171        40884389 :     ResourceArrayEnlarge(&(owner->relrefarr));
 6840                          1172        40884389 : }
                               1173                 : 
                               1174                 : /*
 6840 tgl                      1175 ECB             :  * Remember that a relcache reference is owned by a ResourceOwner
                               1176                 :  *
                               1177                 :  * Caller must have previously done ResourceOwnerEnlargeRelationRefs()
                               1178                 :  */
                               1179                 : void
 6840 tgl                      1180 GIC    39145584 : ResourceOwnerRememberRelationRef(ResourceOwner owner, Relation rel)
                               1181                 : {
 2630                          1182        39145584 :     ResourceArrayAdd(&(owner->relrefarr), PointerGetDatum(rel));
 6840                          1183        39145584 : }
 6840 tgl                      1184 ECB             : 
                               1185                 : /*
                               1186                 :  * Forget that a relcache reference is owned by a ResourceOwner
 6840 tgl                      1187 EUB             :  */
                               1188                 : void
 6840 tgl                      1189 CBC    39145584 : ResourceOwnerForgetRelationRef(ResourceOwner owner, Relation rel)
                               1190                 : {
 2630 tgl                      1191 GIC    39145584 :     if (!ResourceArrayRemove(&(owner->relrefarr), PointerGetDatum(rel)))
 2630 tgl                      1192 UIC           0 :         elog(ERROR, "relcache reference %s is not owned by resource owner %s",
                               1193                 :              RelationGetRelationName(rel), owner->name);
 6840 tgl                      1194 GIC    39145584 : }
                               1195                 : 
                               1196                 : /*
                               1197                 :  * Debugging subroutine
                               1198                 :  */
 6589 tgl                      1199 ECB             : static void
 6589 tgl                      1200 UIC           0 : PrintRelCacheLeakWarning(Relation rel)
 6589 tgl                      1201 ECB             : {
 6589 tgl                      1202 LBC           0 :     elog(WARNING, "relcache reference leak: relation \"%s\" not closed",
                               1203                 :          RelationGetRelationName(rel));
 6589 tgl                      1204 UIC           0 : }
                               1205                 : 
                               1206                 : /*
                               1207                 :  * Make sure there is room for at least one more entry in a ResourceOwner's
                               1208                 :  * plancache reference array.
                               1209                 :  *
 5871 tgl                      1210 ECB             :  * This is separate from actually inserting an entry because if we run out
                               1211                 :  * of memory, it's critical to do so *before* acquiring the resource.
                               1212                 :  */
                               1213                 : void
 5871 tgl                      1214 GIC       83803 : ResourceOwnerEnlargePlanCacheRefs(ResourceOwner owner)
                               1215                 : {
 2630                          1216           83803 :     ResourceArrayEnlarge(&(owner->planrefarr));
 5871                          1217           83803 : }
                               1218                 : 
 5871 tgl                      1219 ECB             : /*
                               1220                 :  * Remember that a plancache reference is owned by a ResourceOwner
                               1221                 :  *
 5871 tgl                      1222 EUB             :  * Caller must have previously done ResourceOwnerEnlargePlanCacheRefs()
                               1223                 :  */
 5871 tgl                      1224 ECB             : void
 5624 bruce                    1225 GIC       83803 : ResourceOwnerRememberPlanCacheRef(ResourceOwner owner, CachedPlan *plan)
                               1226                 : {
 2630 tgl                      1227           83803 :     ResourceArrayAdd(&(owner->planrefarr), PointerGetDatum(plan));
 5871                          1228           83803 : }
                               1229                 : 
                               1230                 : /*
                               1231                 :  * Forget that a plancache reference is owned by a ResourceOwner
                               1232                 :  */
                               1233                 : void
 5624 bruce                    1234 CBC       83803 : ResourceOwnerForgetPlanCacheRef(ResourceOwner owner, CachedPlan *plan)
                               1235                 : {
 2630 tgl                      1236           83803 :     if (!ResourceArrayRemove(&(owner->planrefarr), PointerGetDatum(plan)))
 2630 tgl                      1237 LBC           0 :         elog(ERROR, "plancache reference %p is not owned by resource owner %s",
                               1238                 :              plan, owner->name);
 5871 tgl                      1239 GIC       83803 : }
                               1240                 : 
                               1241                 : /*
                               1242                 :  * Debugging subroutine
                               1243                 :  */
                               1244                 : static void
 5624 bruce                    1245 LBC           0 : PrintPlanCacheLeakWarning(CachedPlan *plan)
                               1246                 : {
 5871 tgl                      1247               0 :     elog(WARNING, "plancache reference leak: plan %p not closed", plan);
                               1248               0 : }
                               1249                 : 
                               1250                 : /*
                               1251                 :  * Make sure there is room for at least one more entry in a ResourceOwner's
                               1252                 :  * tupdesc reference array.
                               1253                 :  *
 6141 tgl                      1254 ECB             :  * This is separate from actually inserting an entry because if we run out
                               1255                 :  * of memory, it's critical to do so *before* acquiring the resource.
                               1256                 :  */
 6141 tgl                      1257 EUB             : void
 6141 tgl                      1258 GIC    21264947 : ResourceOwnerEnlargeTupleDescs(ResourceOwner owner)
 6141 tgl                      1259 ECB             : {
 2630 tgl                      1260 GIC    21264947 :     ResourceArrayEnlarge(&(owner->tupdescarr));
 6141                          1261        21264947 : }
                               1262                 : 
                               1263                 : /*
                               1264                 :  * Remember that a tupdesc reference is owned by a ResourceOwner
 6141 tgl                      1265 EUB             :  *
                               1266                 :  * Caller must have previously done ResourceOwnerEnlargeTupleDescs()
                               1267                 :  */
                               1268                 : void
 6141 tgl                      1269 GBC    21264947 : ResourceOwnerRememberTupleDesc(ResourceOwner owner, TupleDesc tupdesc)
                               1270                 : {
 2630 tgl                      1271 GIC    21264947 :     ResourceArrayAdd(&(owner->tupdescarr), PointerGetDatum(tupdesc));
 6141                          1272        21264947 : }
                               1273                 : 
                               1274                 : /*
                               1275                 :  * Forget that a tupdesc reference is owned by a ResourceOwner
                               1276                 :  */
                               1277                 : void
                               1278        21264947 : ResourceOwnerForgetTupleDesc(ResourceOwner owner, TupleDesc tupdesc)
 6141 tgl                      1279 ECB             : {
 2630 tgl                      1280 GIC    21264947 :     if (!ResourceArrayRemove(&(owner->tupdescarr), PointerGetDatum(tupdesc)))
 2630 tgl                      1281 LBC           0 :         elog(ERROR, "tupdesc reference %p is not owned by resource owner %s",
 2630 tgl                      1282 ECB             :              tupdesc, owner->name);
 6141 tgl                      1283 GIC    21264947 : }
                               1284                 : 
                               1285                 : /*
                               1286                 :  * Debugging subroutine
                               1287                 :  */
                               1288                 : static void
 6141 tgl                      1289 UIC           0 : PrintTupleDescLeakWarning(TupleDesc tupdesc)
 6141 tgl                      1290 ECB             : {
 6141 tgl                      1291 UIC           0 :     elog(WARNING,
 6141 tgl                      1292 ECB             :          "TupleDesc reference leak: TupleDesc %p (%u,%d) still referenced",
                               1293                 :          tupdesc, tupdesc->tdtypeid, tupdesc->tdtypmod);
 6141 tgl                      1294 UIC           0 : }
                               1295                 : 
                               1296                 : /*
                               1297                 :  * Make sure there is room for at least one more entry in a ResourceOwner's
                               1298                 :  * snapshot reference array.
 5248 alvherre                 1299 ECB             :  *
                               1300                 :  * This is separate from actually inserting an entry because if we run out
                               1301                 :  * of memory, it's critical to do so *before* acquiring the resource.
 5248 alvherre                 1302 EUB             :  */
                               1303                 : void
 5248 alvherre                 1304 CBC     8845361 : ResourceOwnerEnlargeSnapshots(ResourceOwner owner)
                               1305                 : {
 2630 tgl                      1306 GIC     8845361 :     ResourceArrayEnlarge(&(owner->snapshotarr));
 5248 alvherre                 1307         8845361 : }
                               1308                 : 
                               1309                 : /*
 5248 alvherre                 1310 EUB             :  * Remember that a snapshot reference is owned by a ResourceOwner
                               1311                 :  *
                               1312                 :  * Caller must have previously done ResourceOwnerEnlargeSnapshots()
                               1313                 :  */
                               1314                 : void
 5248 alvherre                 1315 GIC     8845361 : ResourceOwnerRememberSnapshot(ResourceOwner owner, Snapshot snapshot)
                               1316                 : {
 2630 tgl                      1317         8845361 :     ResourceArrayAdd(&(owner->snapshotarr), PointerGetDatum(snapshot));
 5248 alvherre                 1318         8845361 : }
                               1319                 : 
                               1320                 : /*
                               1321                 :  * Forget that a snapshot reference is owned by a ResourceOwner
                               1322                 :  */
 5248 alvherre                 1323 ECB             : void
 5248 alvherre                 1324 GIC     8845361 : ResourceOwnerForgetSnapshot(ResourceOwner owner, Snapshot snapshot)
 5248 alvherre                 1325 ECB             : {
 2630 tgl                      1326 CBC     8845361 :     if (!ResourceArrayRemove(&(owner->snapshotarr), PointerGetDatum(snapshot)))
 2630 tgl                      1327 UIC           0 :         elog(ERROR, "snapshot reference %p is not owned by resource owner %s",
                               1328                 :              snapshot, owner->name);
 5248 alvherre                 1329 GIC     8845361 : }
                               1330                 : 
                               1331                 : /*
                               1332                 :  * Debugging subroutine
                               1333                 :  */
 5248 alvherre                 1334 ECB             : static void
 5248 alvherre                 1335 UIC           0 : PrintSnapshotLeakWarning(Snapshot snapshot)
 5248 alvherre                 1336 ECB             : {
 2630 tgl                      1337 LBC           0 :     elog(WARNING, "Snapshot reference leak: Snapshot %p still referenced",
                               1338                 :          snapshot);
 5248 alvherre                 1339 UIC           0 : }
                               1340                 : 
                               1341                 : 
                               1342                 : /*
 4875 heikki.linnakangas       1343 ECB             :  * Make sure there is room for at least one more entry in a ResourceOwner's
                               1344                 :  * files reference array.
                               1345                 :  *
 4875 heikki.linnakangas       1346 EUB             :  * This is separate from actually inserting an entry because if we run out
                               1347                 :  * of memory, it's critical to do so *before* acquiring the resource.
 4875 heikki.linnakangas       1348 ECB             :  */
                               1349                 : void
 4875 heikki.linnakangas       1350 GIC        7446 : ResourceOwnerEnlargeFiles(ResourceOwner owner)
                               1351                 : {
 2630 tgl                      1352            7446 :     ResourceArrayEnlarge(&(owner->filearr));
 4875 heikki.linnakangas       1353            7446 : }
 4875 heikki.linnakangas       1354 EUB             : 
                               1355                 : /*
                               1356                 :  * Remember that a temporary file is owned by a ResourceOwner
                               1357                 :  *
                               1358                 :  * Caller must have previously done ResourceOwnerEnlargeFiles()
                               1359                 :  */
                               1360                 : void
 4875 heikki.linnakangas       1361 GIC        5110 : ResourceOwnerRememberFile(ResourceOwner owner, File file)
                               1362                 : {
 2630 tgl                      1363            5110 :     ResourceArrayAdd(&(owner->filearr), FileGetDatum(file));
 4875 heikki.linnakangas       1364            5110 : }
                               1365                 : 
                               1366                 : /*
                               1367                 :  * Forget that a temporary file is owned by a ResourceOwner
                               1368                 :  */
 4875 heikki.linnakangas       1369 ECB             : void
 4875 heikki.linnakangas       1370 GIC        5110 : ResourceOwnerForgetFile(ResourceOwner owner, File file)
 4875 heikki.linnakangas       1371 ECB             : {
 2630 tgl                      1372 CBC        5110 :     if (!ResourceArrayRemove(&(owner->filearr), FileGetDatum(file)))
 2630 tgl                      1373 UIC           0 :         elog(ERROR, "temporary file %d is not owned by resource owner %s",
                               1374                 :              file, owner->name);
 4875 heikki.linnakangas       1375 GIC        5110 : }
                               1376                 : 
                               1377                 : /*
                               1378                 :  * Debugging subroutine
                               1379                 :  */
 4875 heikki.linnakangas       1380 ECB             : static void
 4875 heikki.linnakangas       1381 UIC           0 : PrintFileLeakWarning(File file)
 4875 heikki.linnakangas       1382 ECB             : {
 2630 tgl                      1383 LBC           0 :     elog(WARNING, "temporary file leak: File %d still referenced",
                               1384                 :          file);
 4875 heikki.linnakangas       1385 UIC           0 : }
                               1386                 : 
                               1387                 : /*
                               1388                 :  * Make sure there is room for at least one more entry in a ResourceOwner's
 3469 rhaas                    1389 ECB             :  * dynamic shmem segment reference array.
                               1390                 :  *
                               1391                 :  * This is separate from actually inserting an entry because if we run out
 3469 rhaas                    1392 EUB             :  * of memory, it's critical to do so *before* acquiring the resource.
                               1393                 :  */
 3469 rhaas                    1394 ECB             : void
 3469 rhaas                    1395 GIC       14798 : ResourceOwnerEnlargeDSMs(ResourceOwner owner)
                               1396                 : {
 2630 tgl                      1397           14798 :     ResourceArrayEnlarge(&(owner->dsmarr));
 3469 rhaas                    1398           14798 : }
                               1399                 : 
 3469 rhaas                    1400 EUB             : /*
                               1401                 :  * Remember that a dynamic shmem segment is owned by a ResourceOwner
                               1402                 :  *
                               1403                 :  * Caller must have previously done ResourceOwnerEnlargeDSMs()
                               1404                 :  */
                               1405                 : void
 3469 rhaas                    1406 GIC       14798 : ResourceOwnerRememberDSM(ResourceOwner owner, dsm_segment *seg)
                               1407                 : {
 2630 tgl                      1408           14798 :     ResourceArrayAdd(&(owner->dsmarr), PointerGetDatum(seg));
 3469 rhaas                    1409           14798 : }
                               1410                 : 
                               1411                 : /*
                               1412                 :  * Forget that a dynamic shmem segment is owned by a ResourceOwner
                               1413                 :  */
                               1414                 : void
 3469 rhaas                    1415 CBC       14798 : ResourceOwnerForgetDSM(ResourceOwner owner, dsm_segment *seg)
                               1416                 : {
 2630 tgl                      1417           14798 :     if (!ResourceArrayRemove(&(owner->dsmarr), PointerGetDatum(seg)))
 2630 tgl                      1418 LBC           0 :         elog(ERROR, "dynamic shared memory segment %u is not owned by resource owner %s",
                               1419                 :              dsm_segment_handle(seg), owner->name);
 3469 rhaas                    1420 GIC       14798 : }
                               1421                 : 
                               1422                 : /*
                               1423                 :  * Debugging subroutine
                               1424                 :  */
                               1425                 : static void
 3469 rhaas                    1426 LBC           0 : PrintDSMLeakWarning(dsm_segment *seg)
                               1427                 : {
 2630 tgl                      1428               0 :     elog(WARNING, "dynamic shared memory leak: segment %u still referenced",
 3469 rhaas                    1429 ECB             :          dsm_segment_handle(seg));
 3469 rhaas                    1430 UIC           0 : }
                               1431                 : 
                               1432                 : /*
                               1433                 :  * Make sure there is room for at least one more entry in a ResourceOwner's
                               1434                 :  * JIT context reference array.
 1845 andres                   1435 ECB             :  *
                               1436                 :  * This is separate from actually inserting an entry because if we run out of
                               1437                 :  * memory, it's critical to do so *before* acquiring the resource.
 1845 andres                   1438 EUB             :  */
                               1439                 : void
 1845 andres                   1440 CBC         839 : ResourceOwnerEnlargeJIT(ResourceOwner owner)
                               1441                 : {
 1845 andres                   1442 GIC         839 :     ResourceArrayEnlarge(&(owner->jitarr));
                               1443             839 : }
                               1444                 : 
                               1445                 : /*
 1845 andres                   1446 EUB             :  * Remember that a JIT context is owned by a ResourceOwner
                               1447                 :  *
                               1448                 :  * Caller must have previously done ResourceOwnerEnlargeJIT()
                               1449                 :  */
                               1450                 : void
 1845 andres                   1451 GIC         839 : ResourceOwnerRememberJIT(ResourceOwner owner, Datum handle)
                               1452                 : {
                               1453             839 :     ResourceArrayAdd(&(owner->jitarr), handle);
                               1454             839 : }
                               1455                 : 
                               1456                 : /*
                               1457                 :  * Forget that a JIT context is owned by a ResourceOwner
                               1458                 :  */
                               1459                 : void
 1845 andres                   1460 CBC         839 : ResourceOwnerForgetJIT(ResourceOwner owner, Datum handle)
                               1461                 : {
                               1462             839 :     if (!ResourceArrayRemove(&(owner->jitarr), handle))
 1845 andres                   1463 LBC           0 :         elog(ERROR, "JIT context %p is not owned by resource owner %s",
                               1464                 :              DatumGetPointer(handle), owner->name);
 1845 andres                   1465 GIC         839 : }
                               1466                 : 
                               1467                 : /*
                               1468                 :  * Make sure there is room for at least one more entry in a ResourceOwner's
                               1469                 :  * cryptohash context reference array.
                               1470                 :  *
  856 michael                  1471 ECB             :  * This is separate from actually inserting an entry because if we run out of
                               1472                 :  * memory, it's critical to do so *before* acquiring the resource.
                               1473                 :  */
                               1474                 : void
  856 michael                  1475 GIC      499247 : ResourceOwnerEnlargeCryptoHash(ResourceOwner owner)
                               1476                 : {
                               1477          499247 :     ResourceArrayEnlarge(&(owner->cryptohasharr));
                               1478          499247 : }
                               1479                 : 
  856 michael                  1480 ECB             : /*
                               1481                 :  * Remember that a cryptohash context is owned by a ResourceOwner
                               1482                 :  *
  856 michael                  1483 EUB             :  * Caller must have previously done ResourceOwnerEnlargeCryptoHash()
                               1484                 :  */
  856 michael                  1485 ECB             : void
  856 michael                  1486 GIC      499247 : ResourceOwnerRememberCryptoHash(ResourceOwner owner, Datum handle)
                               1487                 : {
                               1488          499247 :     ResourceArrayAdd(&(owner->cryptohasharr), handle);
                               1489          499247 : }
                               1490                 : 
  856 michael                  1491 EUB             : /*
                               1492                 :  * Forget that a cryptohash context is owned by a ResourceOwner
                               1493                 :  */
                               1494                 : void
  856 michael                  1495 GBC      499242 : ResourceOwnerForgetCryptoHash(ResourceOwner owner, Datum handle)
                               1496                 : {
  856 michael                  1497 GIC      499242 :     if (!ResourceArrayRemove(&(owner->cryptohasharr), handle))
  856 michael                  1498 UIC           0 :         elog(ERROR, "cryptohash context %p is not owned by resource owner %s",
                               1499                 :              DatumGetPointer(handle), owner->name);
  856 michael                  1500 GIC      499242 : }
                               1501                 : 
                               1502                 : /*
                               1503                 :  * Debugging subroutine
                               1504                 :  */
  856 michael                  1505 ECB             : static void
  856 michael                  1506 UIC           0 : PrintCryptoHashLeakWarning(Datum handle)
  856 michael                  1507 ECB             : {
  856 michael                  1508 LBC           0 :     elog(WARNING, "cryptohash context reference leak: context %p still referenced",
                               1509                 :          DatumGetPointer(handle));
  856 michael                  1510 UIC           0 : }
                               1511                 : 
                               1512                 : /*
                               1513                 :  * Make sure there is room for at least one more entry in a ResourceOwner's
                               1514                 :  * hmac context reference array.
                               1515                 :  *
  736 michael                  1516 ECB             :  * This is separate from actually inserting an entry because if we run out of
                               1517                 :  * memory, it's critical to do so *before* acquiring the resource.
                               1518                 :  */
                               1519                 : void
  736 michael                  1520 GIC         216 : ResourceOwnerEnlargeHMAC(ResourceOwner owner)
                               1521                 : {
                               1522             216 :     ResourceArrayEnlarge(&(owner->hmacarr));
                               1523             216 : }
                               1524                 : 
  736 michael                  1525 ECB             : /*
                               1526                 :  * Remember that a HMAC context is owned by a ResourceOwner
                               1527                 :  *
  736 michael                  1528 EUB             :  * Caller must have previously done ResourceOwnerEnlargeHMAC()
                               1529                 :  */
  736 michael                  1530 ECB             : void
  736 michael                  1531 GIC         216 : ResourceOwnerRememberHMAC(ResourceOwner owner, Datum handle)
                               1532                 : {
                               1533             216 :     ResourceArrayAdd(&(owner->hmacarr), handle);
                               1534             216 : }
                               1535                 : 
                               1536                 : /*
                               1537                 :  * Forget that a HMAC context is owned by a ResourceOwner
                               1538                 :  */
                               1539                 : void
  736 michael                  1540 CBC         216 : ResourceOwnerForgetHMAC(ResourceOwner owner, Datum handle)
                               1541                 : {
                               1542             216 :     if (!ResourceArrayRemove(&(owner->hmacarr), handle))
  736 michael                  1543 LBC           0 :         elog(ERROR, "HMAC context %p is not owned by resource owner %s",
                               1544                 :              DatumGetPointer(handle), owner->name);
  736 michael                  1545 GIC         216 : }
                               1546                 : 
                               1547                 : /*
                               1548                 :  * Debugging subroutine
                               1549                 :  */
                               1550                 : static void
  736 michael                  1551 LBC           0 : PrintHMACLeakWarning(Datum handle)
                               1552                 : {
                               1553               0 :     elog(WARNING, "HMAC context reference leak: context %p still referenced",
  736 michael                  1554 ECB             :          DatumGetPointer(handle));
  736 michael                  1555 UIC           0 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a