pthread_cancel & perl_destruct

[email protected] (shibu)
Newsgroups perl.xs
Organization http://groups.google.com
Message-ID <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.