Please submit as a context diff (made with diff -c) and send it to the -patches list, rather than -hackers.


cheers

andrew

[EMAIL PROTECTED] wrote:

In plperl.c, there are some memory leaks, fixed in the following diff file.
Becuase Perl_eval_pv doesnot release stack, repitition of calling
'plperl_trigger_build_args' makes stack growing up.

The next simple example exhaust memory:(using perl v5.8.0)
while (1) {
 AV *av = newAV();
 av_undef(av);
}.
I cannot understand the behavior of AV, so, plperl_get_keys, plperl_get_key, and
plperl_get_elem are deleted, and simply implemented by hv_iter* inlined in the
loop.


Tetsuya.



diff plperl.c plperl.c.org

236,237c236
< SV *rv = NULL;
< SV *ret = NULL;
---


SV *rv;


239d237
< char *s;
305,309c303
< ENTER;
< SAVETMPS;
< ret = newSVsv (perl_eval_pv(SvPV(rv, PL_na), TRUE));
< FREETMPS;
< LEAVE;
---


rv = perl_eval_pv(SvPV(rv, PL_na), TRUE);


312d305
< SvREFCNT_dec(rv);
314c307
< return ret;
---


return rv;


320a314,316


char *key;
I32 klen;
SV *val;


325,326c321
< hv_iterinit(hv);
< while (hv_iternext(hv)){
---


while (val = hv_iternextsv(hv, (char**)&key, &klen)){


332a328,371


static
AV*
plperl_get_keys(HV* hv)
{
        AV *ret;
        SV **svp;
        int key_count;
        SV *val;
        char *key;
        I32 klen;
        key_count = 0;
        ret = newAV();
        
        while (val = hv_iternextsv(hv, (char**)&key, &klen)){
                av_store(ret, key_count, eval_pv(key, TRUE));
                key_count++;
        }
        
        return ret;
}

static
char*
plperl_get_key(AV* keys, int index)
{
        SV **svp;
        int av_len;
        
        av_len = av_len(keys)+1;
        if (index < av_len) svp = av_fetch(keys, index, FALSE); else return 
NULL;
        return SvPV(*svp, PL_na);
}

static
char*
plperl_get_elem(HV* hash, char* key)
{
        SV **svp;
        if (hv_exists_ent(hash, eval_pv(key, TRUE), FALSE))
                svp = hv_fetch(hash, key, strlen(key), FALSE); else return NULL;
        
        return SvPV(*svp, PL_na);
}



363a403


plkeys = plperl_get_keys(hvNew);


382d421
< hv_iterinit(hvNew);
384a424


char *src;


388,389d427
< I32 retlen;
< SV *sv;
391,396c429,430
< sv = hv_iternextsv(hvNew, &platt, &retlen);
< if (sv == NULL)
< elog(FATAL, "plperl: interpreter is probably corrupted");
< plval = SvPV(sv, PL_na);
< if (plval == NULL)
< elog(FATAL, "plperl: interpreter is probably corrupted");
---


platt = plperl_get_key(plkeys, j);


403a438,440


plval = plperl_get_elem(hvNew, platt);
if (plval == NULL)
elog(FATAL, "plperl: interpreter is probably corrupted");


413,428c450,455
< Oid ti;
< < ti = SPI_gettypeid(tupdesc, modattrs[j]);
< if ( ( (ti != TEXTOID) && (ti != BPCHAROID) && (ti != VARCHAROID) ) && ( (strlen(plval) == 0) || (strcmp(plval, "(null)") == 0) ) )
< {
< modvalues[j] = (Datum) 0;
< modnulls[j] = 'n';
< }
< else
< {
< modvalues[j] = FunctionCall3(&finfo,
< CStringGetDatum(plval),
< ObjectIdGetDatum(typelem),
< Int32GetDatum(tupdesc->attrs[atti]->atttypmod));
< modnulls[j] = ' ';
< }
---


src = plval;
modvalues[j] = FunctionCall3(&finfo,
CStringGetDatum(src),
ObjectIdGetDatum(typelem),
Int32GetDatum(tupdesc->attrs[atti]->atttypmod));
modnulls[j] = ' ';


877d903
<    SvREFCNT_dec(svTD);

---------------------------(end of broadcast)---------------------------
TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]




---------------------------(end of broadcast)--------------------------- TIP 4: Don't 'kill -9' the postmaster

Reply via email to