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

Reply via email to