diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2012-09-13 13:44:20 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2012-09-13 13:44:20 -0400 |
commit | 9afc6481117d2dd936e752da0424a2b6b05f6459 (patch) | |
tree | 66e325583bc8dc36a00197fe89047ee2670ce18b /src | |
parent | a20993608a65b9896b4c05cb7061bc60d6f1840a (diff) |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/pl/plperl/plperl.c | 42 |
1 files changed, 19 insertions, 23 deletions
diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 2c39edac5bd..c1e81b4d029 100644 --- a/src/pl/plperl/plperl.c +++ b/src/pl/plperl/plperl.c @@ -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"); |