Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit d3a4d63

Browse files
author
Neil Conway
committed
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.
1 parent 25b9b1b commit d3a4d63

File tree

1 file changed

+32
-38
lines changed

1 file changed

+32
-38
lines changed

src/backend/utils/mb/mbutils.c

+32-38
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@
44
* (currently mule internal code (mic) is used)
55
* Tatsuo Ishii
66
*
7-
* $PostgreSQL: pgsql/src/backend/utils/mb/mbutils.c,v 1.54 2006/01/11 08:43:12 neilc Exp $
7+
* $PostgreSQL: pgsql/src/backend/utils/mb/mbutils.c,v 1.55 2006/01/12 22:04:02 neilc Exp $
88
*/
99
#include "postgres.h"
1010

1111
#include "access/xact.h"
12+
#include "catalog/namespace.h"
1213
#include "miscadmin.h"
1314
#include "mb/pg_wchar.h"
1415
#include "utils/builtins.h"
1516
#include "utils/memutils.h"
1617
#include "utils/syscache.h"
17-
#include "catalog/namespace.h"
1818

1919
/*
2020
* 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];
2525
static pg_enc2name *DatabaseEncoding = &pg_enc2name_tbl[PG_SQL_ASCII];
2626

2727
/*
28-
* Caches for conversion function info. Note that these values are
29-
* allocated in TopMemoryContext so that they survive across
30-
* transactions. See SetClientEncoding() for more details.
28+
* Caches for conversion function info. These values are allocated in
29+
* MbProcContext. That context is a child of TopMemoryContext,
30+
* which allows these values to survive across transactions. See
31+
* SetClientEncoding() for more details.
3132
*/
33+
static MemoryContext MbProcContext = NULL;
3234
static FmgrInfo *ToServerConvProc = NULL;
3335
static FmgrInfo *ToClientConvProc = NULL;
3436

@@ -86,22 +88,10 @@ SetClientEncoding(int encoding, bool doit)
8688
if (doit)
8789
{
8890
ClientEncoding = &pg_enc2name_tbl[encoding];
89-
90-
if (ToServerConvProc != NULL)
91-
{
92-
if (ToServerConvProc->fn_extra)
93-
pfree(ToServerConvProc->fn_extra);
94-
pfree(ToServerConvProc);
95-
}
9691
ToServerConvProc = NULL;
97-
98-
if (ToClientConvProc != NULL)
99-
{
100-
if (ToClientConvProc->fn_extra)
101-
pfree(ToClientConvProc->fn_extra);
102-
pfree(ToClientConvProc);
103-
}
10492
ToClientConvProc = NULL;
93+
if (MbProcContext)
94+
MemoryContextReset(MbProcContext);
10595
}
10696
return 0;
10797
}
@@ -134,33 +124,37 @@ SetClientEncoding(int encoding, bool doit)
134124
if (!doit)
135125
return 0;
136126

137-
/*
138-
* load the fmgr info into TopMemoryContext so that it survives outside
139-
* transaction.
140-
*/
141-
oldcontext = MemoryContextSwitchTo(TopMemoryContext);
127+
/* Before loading the new fmgr info, remove the old info, if any */
128+
ToServerConvProc = NULL;
129+
ToClientConvProc = NULL;
130+
if (MbProcContext != NULL)
131+
{
132+
MemoryContextReset(MbProcContext);
133+
}
134+
else
135+
{
136+
/*
137+
* This is the first time through, so create the context. Make
138+
* it a child of TopMemoryContext so that these values survive
139+
* across transactions.
140+
*/
141+
MbProcContext = AllocSetContextCreate(TopMemoryContext,
142+
"MbProcContext",
143+
ALLOCSET_SMALL_MINSIZE,
144+
ALLOCSET_SMALL_INITSIZE,
145+
ALLOCSET_SMALL_MAXSIZE);
146+
}
147+
148+
/* Load the fmgr info into MbProcContext */
149+
oldcontext = MemoryContextSwitchTo(MbProcContext);
142150
to_server = palloc(sizeof(FmgrInfo));
143151
to_client = palloc(sizeof(FmgrInfo));
144152
fmgr_info(to_server_proc, to_server);
145153
fmgr_info(to_client_proc, to_client);
146154
MemoryContextSwitchTo(oldcontext);
147155

148156
ClientEncoding = &pg_enc2name_tbl[encoding];
149-
150-
if (ToServerConvProc != NULL)
151-
{
152-
if (ToServerConvProc->fn_extra)
153-
pfree(ToServerConvProc->fn_extra);
154-
pfree(ToServerConvProc);
155-
}
156157
ToServerConvProc = to_server;
157-
158-
if (ToClientConvProc != NULL)
159-
{
160-
if (ToClientConvProc->fn_extra)
161-
pfree(ToClientConvProc->fn_extra);
162-
pfree(ToClientConvProc);
163-
}
164158
ToClientConvProc = to_client;
165159

166160
return 0;

0 commit comments

Comments
 (0)