Hello,
I have an application which does data collection using embedded perl.
On configuration change my application has to terminate currently
running threads and then re-read the configuration data. While the
cancellation handler trys to deallocate the perl interpreter my
application aborts.
I wrote a sample c code which re-produces the issue. Can someone help
me to solve this issue?
sample code is below.
perltest.c
#include <EXTERN.h>
#include <perl.h>
#define _MULTI_THREADED
#include <pthread.h>
#include <stdio.h>
static PerlInterpreter *my_perl;
/*structre used to pass the argument received in
the main to the thread which runs embedded perl*/
typedef struct pas_data {
int p_argc;
char ** p_argv;
}p_data;
/* cleanup handler for the p_thread */
void cleanupHandler(void *arg)
{
printf("In the cleanup handler\n");
PERL_SET_CONTEXT(my_perl);
perl_destruct(my_perl);
PERL_SET_CONTEXT(my_perl);
perl_free(my_perl);
printf("Exiting the cleanup handler\n");
}
/* function which runs the perl script */
void *threadfunc(p_data *parm)
{
printf("Entered the embedded perl thread\n");
pthread_cleanup_push(cleanupHandler,NULL);
my_perl = perl_alloc();
perl_construct(my_perl);
perl_parse(my_perl, NULL, parm->p_argc, parm->p_argv, NULL);
call_argv("perlprint", G_DISCARD | G_NOARGS, NULL);
perl_destruct(my_perl);
perl_free(my_perl);
pthread_cleanup_pop(0);
return NULL;
}
int main(int argc, char **argv)
{
pthread_t thread;
int rc=0;
p_data * args;
args = malloc(sizeof(p_data));
args->p_argc=argc;
args->p_argv=argv;
/* invoke the embedded perl in a seperate thread */
rc = pthread_create(&thread, NULL, threadfunc, args);
printf("pthread_create(NULL)\n");
/* sleep() isn't a very robust way to wait for the thread */
sleep(5);
printf("Cancel the thread\n");
/* cancel the thread to trigger teh cancellation handler */
rc = pthread_cancel(thread);
printf("pthread_cancel()\n");
sleep(2);
printf("pthread_cancel done()\n");
return 0;
perl subroutine that gets invoked from c code is -
perlprint.pl
#!/usr/bin/perl
sub perlprint
{
$num =15;
while($num--){
sleep(1);
print "$num \n";
}
}
complied the sample code,
cc -o test perltest.c -lpthread `perl -MExtUtils::Embed -e ccopts -e
ldopts`
when the sample is being run,
./test perlprint.pl
pthread_create(NULL)
Entered the embedded perl thread
14
13
12
11
Cancel the thread
pthread_cancel()
In the cleanup handler
Can't undef active subroutine during global destruction.
it terminates abruptly in the cancellation handler while invoking
perl_destruct.
if i comment the perl_destruct(my_perl); line it works fine, but that
will lead to memory leak.
./test perlprint.pl
pthread_create(NULL)
Entered the embedded perl thread
14
13
12
11
Cancel the thread
pthread_cancel()
In the cleanup handler
Exiting the cleanup handler
pthread_cancel done()
Is there a way to deallocate perl in the cleanup handler?
Regards,
Shibu