Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitcac32a9

Browse files
author
Nikita Glukhov
committed
Fix memory leaks in jsonb_toaster methods using cached temporary context
1 parentcdceadf commitcac32a9

File tree

1 file changed

+116
-15
lines changed

1 file changed

+116
-15
lines changed

‎contrib/jsonb_toaster/jsonb_toaster.c

Lines changed: 116 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3652,6 +3652,103 @@ jsonb_toaster_default_toast(Relation rel, Oid toasterid, char cmethod,
36523652
NULL,options,NULL,NULL, false);
36533653
}
36543654

3655+
/* #define JSONB_TOASTER_TRACK_NESTING 1 FIXME this needs PG_TRY/PG_CATCH */
3656+
3657+
#ifdefJSONB_TOASTER_TRACK_NESTING
3658+
staticintjsonb_toaster_nesting_level;
3659+
#endif
3660+
3661+
staticMemoryContextjsonb_toaster_parent_cxt;
3662+
staticMemoryContextjsonb_toaster_temp_cxt;
3663+
3664+
staticvoid
3665+
jsonb_toaster_temp_context_reset_callback(void*arg)
3666+
{
3667+
if (jsonb_toaster_temp_cxt==arg)
3668+
jsonb_toaster_temp_cxt=NULL;
3669+
}
3670+
3671+
staticvoid
3672+
jsonb_toaster_register_temp_context_callback(MemoryContexttemp_cxt)
3673+
{
3674+
MemoryContextCallback*cb;
3675+
3676+
cb=MemoryContextAlloc(temp_cxt,sizeof(*cb));
3677+
cb->func=jsonb_toaster_temp_context_reset_callback;
3678+
cb->arg=temp_cxt;
3679+
3680+
MemoryContextRegisterResetCallback(temp_cxt,cb);
3681+
}
3682+
3683+
staticvoid
3684+
jsonb_toaster_init_temp_context()
3685+
{
3686+
#ifdefJSONB_TOASTER_TRACK_NESTING
3687+
if (jsonb_toaster_nesting_level++>0)
3688+
return;
3689+
#endif
3690+
3691+
if (!jsonb_toaster_temp_cxt||
3692+
jsonb_toaster_parent_cxt!=CurrentMemoryContext)
3693+
{
3694+
MemoryContexttemp_cxt;
3695+
3696+
if (jsonb_toaster_temp_cxt)
3697+
{
3698+
temp_cxt=jsonb_toaster_temp_cxt;
3699+
jsonb_toaster_temp_cxt=NULL;
3700+
MemoryContextDelete(temp_cxt);
3701+
}
3702+
3703+
temp_cxt=AllocSetContextCreate(CurrentMemoryContext,
3704+
"jsonb_toaster temp context",
3705+
ALLOCSET_DEFAULT_SIZES);
3706+
3707+
jsonb_toaster_register_temp_context_callback(temp_cxt);
3708+
3709+
jsonb_toaster_parent_cxt=CurrentMemoryContext;
3710+
jsonb_toaster_temp_cxt=temp_cxt;
3711+
}
3712+
3713+
MemoryContextSwitchTo(jsonb_toaster_temp_cxt);
3714+
3715+
jsonbInitIterators();
3716+
}
3717+
3718+
staticDatum
3719+
jsonb_toaster_free_temp_context(Datumresult)
3720+
{
3721+
MemoryContexttemp_cxt;
3722+
3723+
#ifdefJSONB_TOASTER_TRACK_NESTING
3724+
if (jsonb_toaster_nesting_level-->1)
3725+
return;
3726+
#endif
3727+
3728+
Assert(CurrentMemoryContext==jsonb_toaster_temp_cxt);
3729+
3730+
jsonbFreeIterators();
3731+
3732+
MemoryContextSwitchTo(jsonb_toaster_parent_cxt);
3733+
3734+
/* Copy result from from temporary context, if any */
3735+
if (result)
3736+
{
3737+
intsize=VARSIZE_ANY(result);
3738+
3739+
result=PointerGetDatum(memcpy(palloc(size),DatumGetPointer(result),size));
3740+
}
3741+
3742+
temp_cxt=jsonb_toaster_temp_cxt;
3743+
MemoryContextReset(temp_cxt);
3744+
3745+
/* Restore jsonb_toaster_temp_cxt after reset callback execution */
3746+
jsonb_toaster_temp_cxt=temp_cxt;
3747+
jsonb_toaster_register_temp_context_callback(temp_cxt);
3748+
3749+
returnresult;
3750+
}
3751+
36553752
staticDatum
36563753
jsonb_toaster_toast(Relationrel,Oidtoasterid,
36573754
Datumnew_val,Datumold_val,
@@ -3661,7 +3758,7 @@ jsonb_toaster_toast(Relation rel, Oid toasterid,
36613758
Datumres;
36623759
charcmethod=TOAST_PGLZ_COMPRESSION;
36633760

3664-
jsonbInitIterators();
3761+
jsonb_toaster_init_temp_context();
36653762

36663763
new_js=DatumGetJsonbPC(new_val,NULL/* FIXME alloca */, false);
36673764

@@ -3674,9 +3771,13 @@ jsonb_toaster_toast(Relation rel, Oid toasterid,
36743771
new_val,new_js,
36753772
max_inline_size,options);
36763773

3677-
res=res== (Datum)0 ?new_val :res;
3678-
3679-
jsonbFreeIterators();
3774+
if (res== (Datum)0||res==new_val)
3775+
{
3776+
res=new_val;
3777+
jsonb_toaster_free_temp_context(0);
3778+
}
3779+
else
3780+
res=jsonb_toaster_free_temp_context(res);
36803781

36813782
returnres;
36823783
}
@@ -3691,13 +3792,13 @@ jsonb_toaster_update_toast(Relation rel, Oid toasterid,
36913792
Datumres;
36923793
charcmethod=TOAST_PGLZ_COMPRESSION;
36933794

3694-
jsonbInitIterators();
3795+
jsonb_toaster_init_temp_context();
36953796

36963797
new_js=DatumGetJsonbPC(new_val,NULL, false);
36973798
old_js=DatumGetJsonbPC(old_val,NULL, false);
36983799
res=jsonb_toaster_cmp(rel,toasterid,JsonRoot(new_js),JsonRoot(old_js),cmethod);
36993800

3700-
jsonbFreeIterators();
3801+
res=jsonb_toaster_free_temp_context(res);
37013802

37023803
returnres;
37033804
}
@@ -3710,12 +3811,12 @@ jsonb_toaster_copy_toast(Relation rel, Oid toasterid,
37103811
Datumres;
37113812
charcmethod=TOAST_PGLZ_COMPRESSION;
37123813

3713-
jsonbInitIterators();
3814+
jsonb_toaster_init_temp_context();
37143815

37153816
new_js=DatumGetJsonbPC(new_val,NULL, false);
37163817
res=jsonb_toaster_copy(rel,toasterid,JsonRoot(new_js),cmethod, true);
37173818

3718-
jsonbFreeIterators();
3819+
res=jsonb_toaster_free_temp_context(res);
37193820

37203821
returnres;
37213822
}
@@ -3725,12 +3826,12 @@ jsonb_toaster_delete_toast(Datum val, bool is_speculative)
37253826
{
37263827
Json*js;
37273828

3728-
jsonbInitIterators();
3829+
jsonb_toaster_init_temp_context();
37293830

37303831
js=DatumGetJsonbPC(val,NULL, false);
37313832
jsonb_toaster_delete_recursive(NULL/* XXX rel */,JsonRoot(js), false,is_speculative);
37323833

3733-
jsonbFreeIterators();
3834+
jsonb_toaster_free_temp_context(0);
37343835
}
37353836

37363837
staticDatum
@@ -3742,10 +3843,11 @@ jsonb_toaster_detoast(Datum toastptr, int sliceoffset, int slicelength)
37423843
JsonValuebin;
37433844
void*detoasted;
37443845
intlen;
3846+
MemoryContextmcxt=CurrentMemoryContext;
37453847

37463848
Assert(VARATT_IS_CUSTOM(toastptr));
37473849

3748-
jsonbInitIterators();
3850+
jsonb_toaster_init_temp_context();
37493851

37503852
//js = DatumGetJson(toastptr, &jsonxContainerOps, &jsbuf);
37513853
js=JsonExpand(NULL/* FIXME &jsbuf */,toastptr, false,&jsonxContainerOps);
@@ -3755,10 +3857,8 @@ jsonb_toaster_detoast(Datum toastptr, int sliceoffset, int slicelength)
37553857
detoasted=JsonEncode(&bin,JsonbEncode,NULL);
37563858
len=VARSIZE_ANY_EXHDR(detoasted);
37573859

3758-
jsonbFreeIterators();
3759-
37603860
if (sliceoffset==0&& (slicelength<0||slicelength >=len))
3761-
returnPointerGetDatum(detoasted);
3861+
returnjsonb_toaster_free_temp_context(PointerGetDatum(detoasted));
37623862

37633863
if (sliceoffset<0)
37643864
sliceoffset=0;
@@ -3768,11 +3868,12 @@ jsonb_toaster_detoast(Datum toastptr, int sliceoffset, int slicelength)
37683868
if (slicelength<0||sliceoffset+slicelength>len)
37693869
slicelength=len-sliceoffset;
37703870

3771-
result=palloc(VARHDRSZ+slicelength);
3871+
result=MemoryContextAlloc(mcxt,VARHDRSZ+slicelength);
37723872
SET_VARSIZE(result,VARHDRSZ+slicelength);
37733873
memcpy(VARDATA(result), (char*)VARDATA_ANY(detoasted)+sliceoffset,slicelength);
37743874

37753875
pfree(detoasted);
3876+
jsonb_toaster_free_temp_context(0);
37763877

37773878
returnPointerGetDatum(result);
37783879
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp