Discussion:
perl_parse problem
(too old to reply)
l***@hotmail.com
2006-08-14 08:55:14 UTC
Permalink
Hello all,

I have a question regarding the perl_parse function.
I have a multi threaded application. Each thread is running a function
that creates a perl interpreter and uses it to parse and then run a
perl function from an arbitrary file.
I'm running this application for few days. The same perl scripts run
all the time.
They are simple perl scripts that use a perl extension I wrote.
Important notes:
1. I'm using SWIG in order to connect between perl and c++.
2. The init method that I send to perl_parse initializes my extension.
3. The call to perl_parse is within a critical section (2 threads will
not call perl_parse in the same time).

My problem is that every few hours the perl_parse function fails.
The next try to parse the same perl script succeeds.
Do any of you know why it can happen?
Also, I couldn't find any documentation to the meaning of perl_parse
return values.
How can I check why perl_parse fails?

Thanks,
Lily.

relevant code (my function and xs_init function):


__declspec(dllexport)
long CFTPerlUserExitInstanceRun(char *FileName,char *FuncName,struct
PerlParmInfo *ParmsVec,unsigned int ParmsVecSize,char* pReason,int
*pCount,int *pUserExitRc, int *pPerlParseRc)
{
long lRc = 0;
int count = -1;
PerlInterpreter* my_perl = NULL;


char *embedding[] = { "", FileName};

while (true)
{
my_perl = perl_alloc();
if (my_perl == NULL)
{
lRc = -1;
break;
}


EnterCriticalSection(&g_ParserCS);

try
{
PERL_SET_CONTEXT(my_perl);
PL_perl_destruct_level = 1;
perl_construct(my_perl);
if (pfnBreakHandlerReset)
{
(*pfnBreakHandlerReset)();
}

*pPerlParseRc = perl_parse(my_perl, xs_init, 2, embedding ,
NULL);
lRc = *pPerlParseRc;

LeaveCriticalSection(&g_ParserCS);
}
catch(...)
{
LeaveCriticalSection(&g_ParserCS);
lRc = -6;
break;
}

if (lRc != 0)
{
lRc = -2;
break;
}

dSP;
ENTER;
SAVETMPS;

PUSHMARK(SP);


// push parms to stack
//========================================
char ParmType[MAX_PARM_TYPE_LEN];

for(unsigned int i=0; i<ParmsVecSize; i++)
{
strncpy(ParmType, PERL_WRAP_PACKAGE_NAME,
MAX_PARM_TYPE_LEN-1);
strncat(ParmType, "::", MAX_PARM_TYPE_LEN-3);
strncat(ParmType, ParmsVec[i].parmtype,
MAX_PARM_TYPE_LEN-strlen(PERL_WRAP_PACKAGE_NAME)-3);

SV *pSVParm = sv_newmortal();
sv_setref_pv( pSVParm, ParmType, ParmsVec[i].parm );
XPUSHs(pSVParm);
}
//========================================

PUTBACK;
try
{
count = call_pv(FuncName, G_EVAL|G_SCALAR);
}
catch(...)
{
lRc = -3;
}

SPAGAIN;

// Check the eval first
if (SvTRUE(ERRSV))
{
STRLEN n_a;
strncpy(pReason, SvPV(ERRSV, n_a), MAX_PERL_REASON_LENGTH-1);
lRc = -4;
POPs ;
}
else
{
if (count != 1)
{
*pCount = count;
lRc = -5;
}
else
{
*pUserExitRc = POPi;

}
}

PUTBACK ;
FREETMPS ;
LEAVE ;

break;
}

if (my_perl != NULL)
{
EnterCriticalSection(&g_ParserCS);

try
{
PL_perl_destruct_level = 1;
perl_destruct(my_perl);
if (pfnBreakHandlerReset) {
(*pfnBreakHandlerReset)();
}
LeaveCriticalSection(&g_ParserCS);
}
catch(...)
{
LeaveCriticalSection(&g_ParserCS);
lRc = -7;
}

perl_free(my_perl);
}

return lRc;
}

xs_init(pTHX)
{
char *file = __FILE__;
dXSUB_SYS;

// DynaLoader is a special case
newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);

BOOT_FTPERLWRAP_TYPE)GetProcAddress(hMain, "myboot_PerlWrap");
newXS("PerlWrap::bootstrap", boot_PerlWrap, file);
}
Nick Ing-Simmons
2006-08-31 20:05:07 UTC
Permalink
Post by l***@hotmail.com
Hello all,
I have a question regarding the perl_parse function.
I have a multi threaded application. Each thread is running a function
that creates a perl interpreter and uses it to parse and then run a
perl function from an arbitrary file.
I'm running this application for few days. The same perl scripts run
all the time.
They are simple perl scripts that use a perl extension I wrote.
1. I'm using SWIG in order to connect between perl and c++.
Didn't we discuss threads and SWIG recently.
What did you do to avoid issues we discussed last time?
Post by l***@hotmail.com
2. The init method that I send to perl_parse initializes my extension.
3. The call to perl_parse is within a critical section (2 threads will
not call perl_parse in the same time).
My problem is that every few hours the perl_parse function fails.
The next try to parse the same perl script succeeds.
Do any of you know why it can happen?
Also, I couldn't find any documentation to the meaning of perl_parse
return values.
It resurns
0 on success
value passed to exit() if eval'ed code calls exit() (well perl's my_exit()).
1 if code does C<die> or equivalent.
Post by l***@hotmail.com
How can I check why perl_parse fails?
$@ i.e. ERRSV is probably set to the error message
but I think that will have been writen to STDERR already
Of course if prroblem is related to allocating memory
Post by l***@hotmail.com
Thanks,
Lily.
__declspec(dllexport)
long CFTPerlUserExitInstanceRun(char *FileName,char *FuncName,struct
PerlParmInfo *ParmsVec,unsigned int ParmsVecSize,char* pReason,int
*pCount,int *pUserExitRc, int *pPerlParseRc)
{
long lRc = 0;
int count = -1;
PerlInterpreter* my_perl = NULL;
char *embedding[] = { "", FileName};
while (true)
{
my_perl = perl_alloc();
if (my_perl == NULL)
{
lRc = -1;
break;
}
EnterCriticalSection(&g_ParserCS);
try
{
PERL_SET_CONTEXT(my_perl);
PL_perl_destruct_level = 1;
perl_construct(my_perl);
if (pfnBreakHandlerReset)
{
(*pfnBreakHandlerReset)();
}
*pPerlParseRc = perl_parse(my_perl, xs_init, 2, embedding ,
NULL);
lRc = *pPerlParseRc;
LeaveCriticalSection(&g_ParserCS);
}
catch(...)
{
LeaveCriticalSection(&g_ParserCS);
lRc = -6;
break;
}
if (lRc != 0)
{
lRc = -2;
break;
}
dSP;
ENTER;
SAVETMPS;
PUSHMARK(SP);
// push parms to stack
//========================================
char ParmType[MAX_PARM_TYPE_LEN];
for(unsigned int i=0; i<ParmsVecSize; i++)
{
strncpy(ParmType, PERL_WRAP_PACKAGE_NAME,
MAX_PARM_TYPE_LEN-1);
strncat(ParmType, "::", MAX_PARM_TYPE_LEN-3);
strncat(ParmType, ParmsVec[i].parmtype,
MAX_PARM_TYPE_LEN-strlen(PERL_WRAP_PACKAGE_NAME)-3);
SV *pSVParm = sv_newmortal();
sv_setref_pv( pSVParm, ParmType, ParmsVec[i].parm );
XPUSHs(pSVParm);
}
//========================================
PUTBACK;
try
{
count = call_pv(FuncName, G_EVAL|G_SCALAR);
}
catch(...)
{
lRc = -3;
}
SPAGAIN;
// Check the eval first
if (SvTRUE(ERRSV))
{
STRLEN n_a;
strncpy(pReason, SvPV(ERRSV, n_a), MAX_PERL_REASON_LENGTH-1);
lRc = -4;
POPs ;
}
else
{
if (count != 1)
{
*pCount = count;
lRc = -5;
}
else
{
*pUserExitRc = POPi;
}
}
PUTBACK ;
FREETMPS ;
LEAVE ;
break;
}
if (my_perl != NULL)
{
EnterCriticalSection(&g_ParserCS);
try
{
PL_perl_destruct_level = 1;
perl_destruct(my_perl);
if (pfnBreakHandlerReset) {
(*pfnBreakHandlerReset)();
}
LeaveCriticalSection(&g_ParserCS);
}
catch(...)
{
LeaveCriticalSection(&g_ParserCS);
lRc = -7;
}
perl_free(my_perl);
}
return lRc;
}
xs_init(pTHX)
{
char *file = __FILE__;
dXSUB_SYS;
// DynaLoader is a special case
newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
BOOT_FTPERLWRAP_TYPE)GetProcAddress(hMain, "myboot_PerlWrap");
newXS("PerlWrap::bootstrap", boot_PerlWrap, file);
}
Nick Ing-Simmons
2006-09-02 09:59:08 UTC
Permalink
Post by l***@hotmail.com
Hello all,
I noticed one more thing. You code below has a try {} catch {}.
Perl is C not C++. It does "exceptions" (i.e. eval { die } ) using
setjmp()/longjmp(). That does not automatically co-exist with try/catch.
So if your inner code ever throw-s perl's state will be in indeterminate
state. For example it could leave file handles open, then when process
ran out of file handles next perl attempt could fail.
Don't know why it would recover though.
Post by l***@hotmail.com
__declspec(dllexport)
long CFTPerlUserExitInstanceRun(char *FileName,char *FuncName,struct
PerlParmInfo *ParmsVec,unsigned int ParmsVecSize,char* pReason,int
*pCount,int *pUserExitRc, int *pPerlParseRc)
{
long lRc = 0;
int count = -1;
PerlInterpreter* my_perl = NULL;
char *embedding[] = { "", FileName};
while (true)
{
my_perl = perl_alloc();
if (my_perl == NULL)
{
lRc = -1;
break;
}
EnterCriticalSection(&g_ParserCS);
try
{
PERL_SET_CONTEXT(my_perl);
PL_perl_destruct_level = 1;
perl_construct(my_perl);
if (pfnBreakHandlerReset)
{
(*pfnBreakHandlerReset)();
}
*pPerlParseRc = perl_parse(my_perl, xs_init, 2, embedding ,
NULL);
lRc = *pPerlParseRc;
LeaveCriticalSection(&g_ParserCS);
}
catch(...)
{
LeaveCriticalSection(&g_ParserCS);
lRc = -6;
break;
}
Continue reading on narkive:
Loading...