@ -20,6 +20,7 @@
*/
*/
# include "postgres.h"
# include "postgres.h"
# include "common/cryptohash.h"
# include "common/hashfn.h"
# include "common/hashfn.h"
# include "jit/jit.h"
# include "jit/jit.h"
# include "storage/bufmgr.h"
# include "storage/bufmgr.h"
@ -128,6 +129,7 @@ typedef struct ResourceOwnerData
ResourceArray filearr ; /* open temporary files */
ResourceArray filearr ; /* open temporary files */
ResourceArray dsmarr ; /* dynamic shmem segments */
ResourceArray dsmarr ; /* dynamic shmem segments */
ResourceArray jitarr ; /* JIT contexts */
ResourceArray jitarr ; /* JIT contexts */
ResourceArray cryptohasharr ; /* cryptohash contexts */
/* We can remember up to MAX_RESOWNER_LOCKS references to local locks. */
/* We can remember up to MAX_RESOWNER_LOCKS references to local locks. */
int nlocks ; /* number of owned locks */
int nlocks ; /* number of owned locks */
@ -175,6 +177,7 @@ static void PrintTupleDescLeakWarning(TupleDesc tupdesc);
static void PrintSnapshotLeakWarning ( Snapshot snapshot ) ;
static void PrintSnapshotLeakWarning ( Snapshot snapshot ) ;
static void PrintFileLeakWarning ( File file ) ;
static void PrintFileLeakWarning ( File file ) ;
static void PrintDSMLeakWarning ( dsm_segment * seg ) ;
static void PrintDSMLeakWarning ( dsm_segment * seg ) ;
static void PrintCryptoHashLeakWarning ( Datum handle ) ;
/*****************************************************************************
/*****************************************************************************
@ -444,6 +447,7 @@ ResourceOwnerCreate(ResourceOwner parent, const char *name)
ResourceArrayInit ( & ( owner - > filearr ) , FileGetDatum ( - 1 ) ) ;
ResourceArrayInit ( & ( owner - > filearr ) , FileGetDatum ( - 1 ) ) ;
ResourceArrayInit ( & ( owner - > dsmarr ) , PointerGetDatum ( NULL ) ) ;
ResourceArrayInit ( & ( owner - > dsmarr ) , PointerGetDatum ( NULL ) ) ;
ResourceArrayInit ( & ( owner - > jitarr ) , PointerGetDatum ( NULL ) ) ;
ResourceArrayInit ( & ( owner - > jitarr ) , PointerGetDatum ( NULL ) ) ;
ResourceArrayInit ( & ( owner - > cryptohasharr ) , PointerGetDatum ( NULL ) ) ;
return owner ;
return owner ;
}
}
@ -553,6 +557,17 @@ ResourceOwnerReleaseInternal(ResourceOwner owner,
jit_release_context ( context ) ;
jit_release_context ( context ) ;
}
}
/* Ditto for cryptohash contexts */
while ( ResourceArrayGetAny ( & ( owner - > cryptohasharr ) , & foundres ) )
{
pg_cryptohash_ctx * context =
( pg_cryptohash_ctx * ) PointerGetDatum ( foundres ) ;
if ( isCommit )
PrintCryptoHashLeakWarning ( foundres ) ;
pg_cryptohash_free ( context ) ;
}
}
}
else if ( phase = = RESOURCE_RELEASE_LOCKS )
else if ( phase = = RESOURCE_RELEASE_LOCKS )
{
{
@ -725,6 +740,7 @@ ResourceOwnerDelete(ResourceOwner owner)
Assert ( owner - > filearr . nitems = = 0 ) ;
Assert ( owner - > filearr . nitems = = 0 ) ;
Assert ( owner - > dsmarr . nitems = = 0 ) ;
Assert ( owner - > dsmarr . nitems = = 0 ) ;
Assert ( owner - > jitarr . nitems = = 0 ) ;
Assert ( owner - > jitarr . nitems = = 0 ) ;
Assert ( owner - > cryptohasharr . nitems = = 0 ) ;
Assert ( owner - > nlocks = = 0 | | owner - > nlocks = = MAX_RESOWNER_LOCKS + 1 ) ;
Assert ( owner - > nlocks = = 0 | | owner - > nlocks = = MAX_RESOWNER_LOCKS + 1 ) ;
/*
/*
@ -752,6 +768,7 @@ ResourceOwnerDelete(ResourceOwner owner)
ResourceArrayFree ( & ( owner - > filearr ) ) ;
ResourceArrayFree ( & ( owner - > filearr ) ) ;
ResourceArrayFree ( & ( owner - > dsmarr ) ) ;
ResourceArrayFree ( & ( owner - > dsmarr ) ) ;
ResourceArrayFree ( & ( owner - > jitarr ) ) ;
ResourceArrayFree ( & ( owner - > jitarr ) ) ;
ResourceArrayFree ( & ( owner - > cryptohasharr ) ) ;
pfree ( owner ) ;
pfree ( owner ) ;
}
}
@ -1370,3 +1387,48 @@ ResourceOwnerForgetJIT(ResourceOwner owner, Datum handle)
elog ( ERROR , " JIT context %p is not owned by resource owner %s " ,
elog ( ERROR , " JIT context %p is not owned by resource owner %s " ,
DatumGetPointer ( handle ) , owner - > name ) ;
DatumGetPointer ( handle ) , owner - > name ) ;
}
}
/*
* Make sure there is room for at least one more entry in a ResourceOwner ' s
* cryptohash context reference array .
*
* This is separate from actually inserting an entry because if we run out of
* memory , it ' s critical to do so * before * acquiring the resource .
*/
void
ResourceOwnerEnlargeCryptoHash ( ResourceOwner owner )
{
ResourceArrayEnlarge ( & ( owner - > cryptohasharr ) ) ;
}
/*
* Remember that a cryptohash context is owned by a ResourceOwner
*
* Caller must have previously done ResourceOwnerEnlargeCryptoHash ( )
*/
void
ResourceOwnerRememberCryptoHash ( ResourceOwner owner , Datum handle )
{
ResourceArrayAdd ( & ( owner - > cryptohasharr ) , handle ) ;
}
/*
* Forget that a cryptohash context is owned by a ResourceOwner
*/
void
ResourceOwnerForgetCryptoHash ( ResourceOwner owner , Datum handle )
{
if ( ! ResourceArrayRemove ( & ( owner - > cryptohasharr ) , handle ) )
elog ( ERROR , " cryptohash context %p is not owned by resource owner %s " ,
DatumGetPointer ( handle ) , owner - > name ) ;
}
/*
* Debugging subroutine
*/
static void
PrintCryptoHashLeakWarning ( Datum handle )
{
elog ( WARNING , " cryptohash context reference leak: context %p still referenced " ,
DatumGetPointer ( handle ) ) ;
}