mirror of
https://github.com/postgres/postgres.git
synced 2025-06-26 12:21:12 +03:00
mbutils was previously doing some allocations, including invoking
fmgr_info(), in the TopMemoryContext. I couldn't see that the code actually leaked, but in general I think it's fragile to assume that pfree'ing an FmgrInfo along with its fn_extra field is enough to reclaim all the resources allocated by fmgr_info(). I changed the code to do its allocations in a new child context of TopMemoryContext, MbProcContext. When we want to release the allocations we can just reset the context, which is cleaner.
This commit is contained in:
@ -4,17 +4,17 @@
|
|||||||
* (currently mule internal code (mic) is used)
|
* (currently mule internal code (mic) is used)
|
||||||
* Tatsuo Ishii
|
* Tatsuo Ishii
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/mb/mbutils.c,v 1.54 2006/01/11 08:43:12 neilc Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/mb/mbutils.c,v 1.55 2006/01/12 22:04:02 neilc Exp $
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "access/xact.h"
|
#include "access/xact.h"
|
||||||
|
#include "catalog/namespace.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "mb/pg_wchar.h"
|
#include "mb/pg_wchar.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/memutils.h"
|
#include "utils/memutils.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
#include "catalog/namespace.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We handle for actual FE and BE encoding setting encoding-identificator
|
* We handle for actual FE and BE encoding setting encoding-identificator
|
||||||
@ -25,10 +25,12 @@ static pg_enc2name *ClientEncoding = &pg_enc2name_tbl[PG_SQL_ASCII];
|
|||||||
static pg_enc2name *DatabaseEncoding = &pg_enc2name_tbl[PG_SQL_ASCII];
|
static pg_enc2name *DatabaseEncoding = &pg_enc2name_tbl[PG_SQL_ASCII];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Caches for conversion function info. Note that these values are
|
* Caches for conversion function info. These values are allocated in
|
||||||
* allocated in TopMemoryContext so that they survive across
|
* MbProcContext. That context is a child of TopMemoryContext,
|
||||||
* transactions. See SetClientEncoding() for more details.
|
* which allows these values to survive across transactions. See
|
||||||
|
* SetClientEncoding() for more details.
|
||||||
*/
|
*/
|
||||||
|
static MemoryContext MbProcContext = NULL;
|
||||||
static FmgrInfo *ToServerConvProc = NULL;
|
static FmgrInfo *ToServerConvProc = NULL;
|
||||||
static FmgrInfo *ToClientConvProc = NULL;
|
static FmgrInfo *ToClientConvProc = NULL;
|
||||||
|
|
||||||
@ -86,22 +88,10 @@ SetClientEncoding(int encoding, bool doit)
|
|||||||
if (doit)
|
if (doit)
|
||||||
{
|
{
|
||||||
ClientEncoding = &pg_enc2name_tbl[encoding];
|
ClientEncoding = &pg_enc2name_tbl[encoding];
|
||||||
|
|
||||||
if (ToServerConvProc != NULL)
|
|
||||||
{
|
|
||||||
if (ToServerConvProc->fn_extra)
|
|
||||||
pfree(ToServerConvProc->fn_extra);
|
|
||||||
pfree(ToServerConvProc);
|
|
||||||
}
|
|
||||||
ToServerConvProc = NULL;
|
ToServerConvProc = NULL;
|
||||||
|
|
||||||
if (ToClientConvProc != NULL)
|
|
||||||
{
|
|
||||||
if (ToClientConvProc->fn_extra)
|
|
||||||
pfree(ToClientConvProc->fn_extra);
|
|
||||||
pfree(ToClientConvProc);
|
|
||||||
}
|
|
||||||
ToClientConvProc = NULL;
|
ToClientConvProc = NULL;
|
||||||
|
if (MbProcContext)
|
||||||
|
MemoryContextReset(MbProcContext);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -134,11 +124,29 @@ SetClientEncoding(int encoding, bool doit)
|
|||||||
if (!doit)
|
if (!doit)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/*
|
/* Before loading the new fmgr info, remove the old info, if any */
|
||||||
* load the fmgr info into TopMemoryContext so that it survives outside
|
ToServerConvProc = NULL;
|
||||||
* transaction.
|
ToClientConvProc = NULL;
|
||||||
*/
|
if (MbProcContext != NULL)
|
||||||
oldcontext = MemoryContextSwitchTo(TopMemoryContext);
|
{
|
||||||
|
MemoryContextReset(MbProcContext);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This is the first time through, so create the context. Make
|
||||||
|
* it a child of TopMemoryContext so that these values survive
|
||||||
|
* across transactions.
|
||||||
|
*/
|
||||||
|
MbProcContext = AllocSetContextCreate(TopMemoryContext,
|
||||||
|
"MbProcContext",
|
||||||
|
ALLOCSET_SMALL_MINSIZE,
|
||||||
|
ALLOCSET_SMALL_INITSIZE,
|
||||||
|
ALLOCSET_SMALL_MAXSIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load the fmgr info into MbProcContext */
|
||||||
|
oldcontext = MemoryContextSwitchTo(MbProcContext);
|
||||||
to_server = palloc(sizeof(FmgrInfo));
|
to_server = palloc(sizeof(FmgrInfo));
|
||||||
to_client = palloc(sizeof(FmgrInfo));
|
to_client = palloc(sizeof(FmgrInfo));
|
||||||
fmgr_info(to_server_proc, to_server);
|
fmgr_info(to_server_proc, to_server);
|
||||||
@ -146,21 +154,7 @@ SetClientEncoding(int encoding, bool doit)
|
|||||||
MemoryContextSwitchTo(oldcontext);
|
MemoryContextSwitchTo(oldcontext);
|
||||||
|
|
||||||
ClientEncoding = &pg_enc2name_tbl[encoding];
|
ClientEncoding = &pg_enc2name_tbl[encoding];
|
||||||
|
|
||||||
if (ToServerConvProc != NULL)
|
|
||||||
{
|
|
||||||
if (ToServerConvProc->fn_extra)
|
|
||||||
pfree(ToServerConvProc->fn_extra);
|
|
||||||
pfree(ToServerConvProc);
|
|
||||||
}
|
|
||||||
ToServerConvProc = to_server;
|
ToServerConvProc = to_server;
|
||||||
|
|
||||||
if (ToClientConvProc != NULL)
|
|
||||||
{
|
|
||||||
if (ToClientConvProc->fn_extra)
|
|
||||||
pfree(ToClientConvProc->fn_extra);
|
|
||||||
pfree(ToClientConvProc);
|
|
||||||
}
|
|
||||||
ToClientConvProc = to_client;
|
ToClientConvProc = to_client;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Reference in New Issue
Block a user