Apothen <[EMAIL PROTECTED]> writes:
>Hi,
>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. 

There can only be one thread "live" in each perl intepreter.
So you either need to allocate a perl intepreter per thread,
or serialize access to the perl data structures in your C/XS cdoe.

In particular you are pushing args onto the perl stack (XPUSHs)
this is clearly nonsense if two threads try and do it to same 
stack at same time. 


>"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?

This is not a trivial task - ask your self whether you really want 
or need to do this - if this is self teaching then plough on ...

Read a book on threading concepts 
Build a threaded perl.
Study the perl threading C sources - we don't really have XS level howto 
docs on threading - if you have questions you can try asking here
but perl5-porters might be better. 
Use pTHX/aTHX/dTHX and PERL_SET_CONTEXT appropriately so macros 
see the right perl interpreter for your thread.

>
>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
>//-----------------------------------------------------------------------------

Reply via email to