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

Lines changed: 32 additions & 38 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy