Keep plperl's current_call_data record on the stack, instead of palloc'ing.

This at least saves some palloc overhead, and should furthermore reduce
the risk of anything going wrong, eg somebody resetting the context the
current_call_data record was in.
This commit is contained in:
Tom Lane 2012-09-13 13:44:20 -04:00
parent a20993608a
commit 9afc648111

View File

@ -1705,10 +1705,15 @@ plperl_call_handler(PG_FUNCTION_ARGS)
Datum retval;
plperl_call_data *save_call_data = current_call_data;
plperl_interp_desc *oldinterp = plperl_active_interp;
plperl_call_data this_call_data;
/* Initialize current-call status record */
MemSet(&this_call_data, 0, sizeof(this_call_data));
this_call_data.fcinfo = fcinfo;
PG_TRY();
{
current_call_data = NULL;
current_call_data = &this_call_data;
if (CALLED_AS_TRIGGER(fcinfo))
retval = PointerGetDatum(plperl_trigger_handler(fcinfo));
else
@ -1716,16 +1721,16 @@ plperl_call_handler(PG_FUNCTION_ARGS)
}
PG_CATCH();
{
if (current_call_data && current_call_data->prodesc)
decrement_prodesc_refcount(current_call_data->prodesc);
if (this_call_data.prodesc)
decrement_prodesc_refcount(this_call_data.prodesc);
current_call_data = save_call_data;
activate_interpreter(oldinterp);
PG_RE_THROW();
}
PG_END_TRY();
if (current_call_data && current_call_data->prodesc)
decrement_prodesc_refcount(current_call_data->prodesc);
if (this_call_data.prodesc)
decrement_prodesc_refcount(this_call_data.prodesc);
current_call_data = save_call_data;
activate_interpreter(oldinterp);
return retval;
@ -1745,8 +1750,12 @@ plperl_inline_handler(PG_FUNCTION_ARGS)
plperl_proc_desc desc;
plperl_call_data *save_call_data = current_call_data;
plperl_interp_desc *oldinterp = plperl_active_interp;
plperl_call_data this_call_data;
ErrorContextCallback pl_error_context;
/* Initialize current-call status record */
MemSet(&this_call_data, 0, sizeof(this_call_data));
/* Set up a callback for error reporting */
pl_error_context.callback = plperl_inline_callback;
pl_error_context.previous = error_context_stack;
@ -1777,14 +1786,15 @@ plperl_inline_handler(PG_FUNCTION_ARGS)
desc.nargs = 0;
desc.reference = NULL;
this_call_data.fcinfo = &fake_fcinfo;
this_call_data.prodesc = &desc;
/* we do not bother with refcounting the fake prodesc */
PG_TRY();
{
SV *perlret;
current_call_data = (plperl_call_data *) palloc0(sizeof(plperl_call_data));
current_call_data->fcinfo = &fake_fcinfo;
current_call_data->prodesc = &desc;
/* we do not bother with refcounting the fake prodesc */
current_call_data = &this_call_data;
if (SPI_connect() != SPI_OK_CONNECT)
elog(ERROR, "could not connect to SPI manager");
@ -2167,13 +2177,6 @@ plperl_func_handler(PG_FUNCTION_ARGS)
ReturnSetInfo *rsi;
ErrorContextCallback pl_error_context;
/*
* Create the call_data before connecting to SPI, so that it is not
* allocated in the SPI memory context
*/
current_call_data = (plperl_call_data *) palloc0(sizeof(plperl_call_data));
current_call_data->fcinfo = fcinfo;
if (SPI_connect() != SPI_OK_CONNECT)
elog(ERROR, "could not connect to SPI manager");
@ -2286,13 +2289,6 @@ plperl_trigger_handler(PG_FUNCTION_ARGS)
HV *hvTD;
ErrorContextCallback pl_error_context;
/*
* Create the call_data before connecting to SPI, so that it is not
* allocated in the SPI memory context
*/
current_call_data = (plperl_call_data *) palloc0(sizeof(plperl_call_data));
current_call_data->fcinfo = fcinfo;
/* Connect to SPI manager */
if (SPI_connect() != SPI_OK_CONNECT)
elog(ERROR, "could not connect to SPI manager");