I am trying to use the thread features in my perl XS module and getting "Segmentation Fault". I am creating two threads at a time and trying to execute a function which calls perl_call_sv() to convert given string to an array. "Segmentation Fault" is happening especially when I use other modules, say, DBI in my main perl script. Can somebody please look into the XS and advise me as what I should to make it working?
I am not explaining the issue clearly. Please let me know.
I would really appreciate your time.
Thanks, APothen.
* test.pl is the calling program
* FieldFmt_M.xs is the XS program.
* Makefile.PL, I have: DEFINE' => '-D_POSIX_REENTRANT_FUNCTIONS -DREENTRANT',
test.pl ======= use FieldFmt_M; my $dbh ;
#Create an anonymous subroutine which will be executed in XS to convert string to an array reference
my($coderef) = sub { my ($sep,$str) = @_ ; $sep = "\\|" if ( $sep eq "|" ) ; my(@a) = split($sep,$str); return [EMAIL PROTECTED] } ; #Create the XS my ($f)= FieldFmt_M->new() ;
#Call the function with the $coderef as an argument $f->Str_to_array($coderef) ;
1; __END__
If I use following coded before Str_to_array() function call, I am getting "Segmentation Fault".
use DBI;
#Connect to the database
$dbh = DBI->connect(dbi:Sybase:...", "user","password", { RaiseError => 1, PrintError => 0} ) ;
if ( !defined($dbh) ) {
die "DBI->Connect() Failed" ;
}
FieldFmt_M.xs =============
#include "EXTERN.h" #include "perl.h" #include <pthread.h> #include "XSUB.h"
void* str_to_array(char *sep, char *str, STRLEN str_len, SV** sv_Arr, SV* sv_codeRef ) {
int count ;
dSP ;
ENTER ;
SAVETMPS;
PUSHMARK(SP) ;
XPUSHs(sv_2mortal(newSVpv(sep,0))) ; XPUSHs(sv_2mortal(newSVpv(str,str_len))) ; PUTBACK ; count = perl_call_sv( sv_codeRef,G_ARRAY) ; SPAGAIN ; if ( count != 1 ) { croak ("Big Trouble calling function, str_to_array\n") ; } *sv_Arr = SvREFCNT_inc(POPs) ;
PUTBACK ; FREETMPS ; LEAVE ; return *sv_Arr; }
void* fn_str_to_array(SV* sv_codeRef) { SV* sv_Arr; AV* av_Arr; SV** sv_Ptr; char str[]={"THIS\tIS\tA\tTEST\tSTRING"}; if (str_to_array("\t",str, strlen(str),&sv_Arr,sv_fPtr) != Nullsv ) { av_Arr = (AV *) SvRV(sv_Arr) ; sv_Ptr = av_fetch(av_Arr,1,0) ; printf("Item 1=%s\n", SvPVX(*sv_Ptr)) ; SvREFCNT_dec(sv_Arr) ; } pthread_exit(0) ; }
int thr_str_to_array(SV* sv_codeRef) {
pthread_t thr_f1, thr_f2, ret_thr; void *status;
for ( int i=1; i<1000; i++ ) {
if (pthread_create(&thr_f1, NULL, fn_str_to_array, sv_fPtr)) { fprintf(stderr,"Can't create thr_f1\n"); croak ("Can't create thr_f1 for str_to_array\n") ; }
if (pthread_create(&thr_f2, NULL, fn_str_to_array, sv_fPtr)) { fprintf(stderr,"Can't create thr_f2\n"); croak ("Can't create thr_f2 for str_to_array\n") ; }
if ( pthread_join(thr_f1, &status)) fprintf(stderr,"thr_f1 join error\n"), exit(1);
if ( pthread_join(thr_f2, &status)) fprintf(stderr,"thr_f2 join error\n"), exit(1); }
}
MODULE = FieldFmt_M PACKAGE = FieldFmt_M
int str_to_array(sv_codeRef) SV * sv_codeRef CODE: { thr_str_to_array(sv_codeRef); } OUTPUT: RETVAL //-----------------------------------------------------------------------------