l***@hotmail.com
2006-08-14 08:55:14 UTC
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);
}
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);
}