Skip Menu |

This queue is for tickets about the Bit-Vector CPAN distribution.

Report information
The Basics
Id: 27367
Status: resolved
Priority: 0/
Queue: Bit-Vector

People
Owner: Nobody in particular
Requestors: jdiepen [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 6.4
Fixed in: (no value)



Subject: Bit-Vector isn't thread-safe
Bit-Vector 6.4 stores the stash pointer to the "Bit::Vector" class in a static variable (probably for performance reasons). This does not work when you attempt to use Bit::Vector from multiple threads (on linux, at least), since that pointer is different for each thread. See attached file "test2.pl" for an example that will attempt to crash bit::vector (within a second or two on my machine). Also attached is a patch that replaces access to the static BitVector_Stash variable with a macro BITVECTOR_STASH that fetches the right pointer from the current thread/interpreter. This patch will make bit-vector a bit slower even if you don't use threads. If needed, it should be fairly easy to change the macro to work quicker if you use a non-threaded perl. This patch was tested on perl-5.8.8 built for i386-linux-thread-multi Cheers, Joost Diepenmaat Zeekat Softwareontwikkeling
Subject: test2.pl
#!/usr/bin/perl -w use threads; use Bit::Vector; use threads::shared; my $lock :shared =1; my @threads; for (0 .. 10) { push @threads,threads->new(\&make_stuff); } sub make_stuff { warn threads->tid," running stuff"; while(1) { Bit::Vector->new( 128); } } sleep 1 while 1;
Subject: perl-Bit-Vector-thread.patch
diff -cr Bit-Vector-6.4/Vector.xs Bit-Vector-6.4-threaded/Vector.xs *** Bit-Vector-6.4/Vector.xs 2004-10-03 10:20:29.000000000 +0200 --- Bit-Vector-6.4-threaded/Vector.xs 2007-06-01 13:59:05.000000000 +0200 *************** *** 1,4 **** ! /*****************************************************************************/ /* */ --- 1,4 ---- ! /* Emacs, this is -*- C -*- mode */ /*****************************************************************************/ /* */ *************** *** 35,41 **** static char *BitVector_Class = "Bit::Vector"; ! static HV *BitVector_Stash; typedef SV *BitVector_Object; typedef SV *BitVector_Handle; --- 35,42 ---- static char *BitVector_Class = "Bit::Vector"; ! ! #define BITVECTOR_STASH gv_stashpv(BitVector_Class,1) typedef SV *BitVector_Object; typedef SV *BitVector_Handle; *************** *** 67,73 **** SvOBJECT(hdl) && \ SvREADONLY(hdl) && \ (SvTYPE(hdl) == SVt_PVMG) && \ ! (SvSTASH(hdl) == BitVector_Stash) && \ (adr = (BitVector_Address)SvIV(hdl)) ) #define BIT_VECTOR_SCALAR(ref,typ,var) \ --- 68,74 ---- SvOBJECT(hdl) && \ SvREADONLY(hdl) && \ (SvTYPE(hdl) == SVt_PVMG) && \ ! (SvSTASH(hdl) == BITVECTOR_STASH) && \ (adr = (BitVector_Address)SvIV(hdl)) ) #define BIT_VECTOR_SCALAR(ref,typ,var) \ *************** *** 151,157 **** BIT_VECTOR_EXCEPTION(rc); exit((int)rc); } - BitVector_Stash = gv_stashpv(BitVector_Class,1); } --- 152,157 ---- *************** *** 240,246 **** address = *slot++; handle = newSViv((IV)address); reference = sv_bless(sv_2mortal(newRV(handle)), ! BitVector_Stash); SvREFCNT_dec(handle); SvREADONLY_on(handle); PUSHs(reference); --- 240,246 ---- address = *slot++; handle = newSViv((IV)address); reference = sv_bless(sv_2mortal(newRV(handle)), ! BITVECTOR_STASH); SvREFCNT_dec(handle); SvREADONLY_on(handle); PUSHs(reference); *************** *** 258,264 **** { handle = newSViv((IV)address); reference = sv_bless(sv_2mortal(newRV(handle)), ! BitVector_Stash); SvREFCNT_dec(handle); SvREADONLY_on(handle); PUSHs(reference); --- 258,264 ---- { handle = newSViv((IV)address); reference = sv_bless(sv_2mortal(newRV(handle)), ! BITVECTOR_STASH); SvREFCNT_dec(handle); SvREADONLY_on(handle); PUSHs(reference); *************** *** 301,307 **** { handle = newSViv((IV)address); reference = sv_bless(sv_2mortal(newRV(handle)), ! BitVector_Stash); SvREFCNT_dec(handle); SvREADONLY_on(handle); PUSHs(reference); --- 301,307 ---- { handle = newSViv((IV)address); reference = sv_bless(sv_2mortal(newRV(handle)), ! BITVECTOR_STASH); SvREFCNT_dec(handle); SvREADONLY_on(handle); PUSHs(reference); *************** *** 344,350 **** { handle = newSViv((IV)address); reference = sv_bless(sv_2mortal(newRV(handle)), ! BitVector_Stash); SvREFCNT_dec(handle); SvREADONLY_on(handle); PUSHs(reference); --- 344,350 ---- { handle = newSViv((IV)address); reference = sv_bless(sv_2mortal(newRV(handle)), ! BITVECTOR_STASH); SvREFCNT_dec(handle); SvREADONLY_on(handle); PUSHs(reference); *************** *** 387,393 **** { handle = newSViv((IV)address); reference = sv_bless(sv_2mortal(newRV(handle)), ! BitVector_Stash); SvREFCNT_dec(handle); SvREADONLY_on(handle); PUSHs(reference); --- 387,393 ---- { handle = newSViv((IV)address); reference = sv_bless(sv_2mortal(newRV(handle)), ! BITVECTOR_STASH); SvREFCNT_dec(handle); SvREADONLY_on(handle); PUSHs(reference); *************** *** 430,436 **** { handle = newSViv((IV)address); reference = sv_bless(sv_2mortal(newRV(handle)), ! BitVector_Stash); SvREFCNT_dec(handle); SvREADONLY_on(handle); PUSHs(reference); --- 430,436 ---- { handle = newSViv((IV)address); reference = sv_bless(sv_2mortal(newRV(handle)), ! BITVECTOR_STASH); SvREFCNT_dec(handle); SvREADONLY_on(handle); PUSHs(reference); *************** *** 458,464 **** { handle = newSViv((IV)address); reference = sv_bless(sv_2mortal(newRV(handle)), ! BitVector_Stash); SvREFCNT_dec(handle); SvREADONLY_on(handle); PUSHs(reference); --- 458,464 ---- { handle = newSViv((IV)address); reference = sv_bless(sv_2mortal(newRV(handle)), ! BITVECTOR_STASH); SvREFCNT_dec(handle); SvREADONLY_on(handle); PUSHs(reference); *************** *** 483,489 **** { handle = newSViv((IV)address); reference = sv_bless(sv_2mortal(newRV(handle)), ! BitVector_Stash); SvREFCNT_dec(handle); SvREADONLY_on(handle); PUSHs(reference); --- 483,489 ---- { handle = newSViv((IV)address); reference = sv_bless(sv_2mortal(newRV(handle)), ! BITVECTOR_STASH); SvREFCNT_dec(handle); SvREADONLY_on(handle); PUSHs(reference); *************** *** 515,521 **** { handle = newSViv((IV)address); reference = sv_bless(sv_2mortal(newRV(handle)), ! BitVector_Stash); SvREFCNT_dec(handle); SvREADONLY_on(handle); PUSHs(reference); --- 515,521 ---- { handle = newSViv((IV)address); reference = sv_bless(sv_2mortal(newRV(handle)), ! BITVECTOR_STASH); SvREFCNT_dec(handle); SvREADONLY_on(handle); PUSHs(reference); *************** *** 571,577 **** } handle = newSViv((IV)address); reference = sv_bless(sv_2mortal(newRV(handle)), ! BitVector_Stash); SvREFCNT_dec(handle); SvREADONLY_on(handle); PUSHs(reference); --- 571,577 ---- } handle = newSViv((IV)address); reference = sv_bless(sv_2mortal(newRV(handle)), ! BITVECTOR_STASH); SvREFCNT_dec(handle); SvREADONLY_on(handle); PUSHs(reference);
Dear Joost, thank you very much, and sorry for the long delay of my response! This should be fixed as you indicated in the next release (version 6.6), due out during the next few days.