diff options
author | Father Chrysostomos <sprout@cpan.org> | 2013-07-05 22:51:50 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2013-08-09 19:44:13 -0700 |
commit | 1dc74fdba201402174cfbd293adc42f5a0bafc22 (patch) | |
tree | bf675ece5baae52ad8e311dd1b9de36514736c4c /cop.h | |
parent | 449dd03960bf018889fc68eb9ff03ef613eb893b (diff) | |
download | perl-1dc74fdba201402174cfbd293adc42f5a0bafc22.tar.gz |
Revert "[perl #117855] Store CopFILEGV in a pad under ithreads"
This reverts commit c82ecf346.
It turn out to be faulty, because a location shared betweens threads
(the cop) was holding a reference count on a pad entry in a particu-
lar thread. So when you free the cop, how do you know where to do
SvREFCNT_dec?
In reverting c82ecf346, this commit still preserves the bug fix from
1311cfc0a7b, but shifts it around.
Diffstat (limited to 'cop.h')
-rw-r--r-- | cop.h | 49 |
1 files changed, 35 insertions, 14 deletions
@@ -389,8 +389,7 @@ struct cop { #ifdef USE_ITHREADS PADOFFSET cop_stashoff; /* offset into PL_stashpad, for the package the line was compiled in */ - PADOFFSET cop_filegvoff; /* PL_filegv offset, for the file name the - following line # is from */ + char * cop_file; /* file name the following line # is from */ #else HV * cop_stash; /* package line was compiled in */ GV * cop_filegv; /* file the following line # is from */ @@ -405,32 +404,54 @@ struct cop { }; #ifdef USE_ITHREADS -# define CopFILEGV(c) PL_filegvpad[(c)->cop_filegvoff] -# define CopFILEGV_set(c,gv) ((c)->cop_filegvoff = (gv) \ - ? allocfilegv((GV *)SvREFCNT_inc_NN(gv)) \ - : 0) +# define CopFILE(c) ((c)->cop_file) +# define CopFILEGV(c) (CopFILE(c) \ + ? gv_fetchfile(CopFILE(c)) : NULL) + +# ifdef NETWARE +# define CopFILE_set(c,pv) ((c)->cop_file = savepv(pv)) +# define CopFILE_setn(c,pv,l) ((c)->cop_file = savepv((pv),(l))) +# else +# define CopFILE_set(c,pv) ((c)->cop_file = savesharedpv(pv)) +# define CopFILE_setn(c,pv,l) ((c)->cop_file = savesharedpvn((pv),(l))) +# endif + +# define CopFILESV(c) (CopFILE(c) \ + ? GvSV(gv_fetchfile(CopFILE(c))) : NULL) +# define CopFILEAV(c) (CopFILE(c) \ + ? GvAV(gv_fetchfile(CopFILE(c))) : NULL) +# define CopFILEAVx(c) (assert_(CopFILE(c)) \ + GvAV(gv_fetchfile(CopFILE(c)))) # define CopSTASH(c) PL_stashpad[(c)->cop_stashoff] # define CopSTASH_set(c,hv) ((c)->cop_stashoff = (hv) \ ? alloccopstash(hv) \ : 0) -# define CopFILE_free(c) S_CopFILE_free(aTHX_ c) +# ifdef NETWARE +# define CopFILE_free(c) SAVECOPFILE_FREE(c) +# else +# define CopFILE_free(c) (PerlMemShared_free(CopFILE(c)),(CopFILE(c) = NULL)) +# endif #else # define CopFILEGV(c) ((c)->cop_filegv) # define CopFILEGV_set(c,gv) ((c)->cop_filegv = (GV*)SvREFCNT_inc(gv)) +# define CopFILE_set(c,pv) CopFILEGV_set((c), gv_fetchfile(pv)) +# define CopFILE_setn(c,pv,l) CopFILEGV_set((c), gv_fetchfile_flags((pv),(l),0)) +# define CopFILESV(c) (CopFILEGV(c) ? GvSV(CopFILEGV(c)) : NULL) +# define CopFILEAV(c) (CopFILEGV(c) ? GvAV(CopFILEGV(c)) : NULL) +# ifdef DEBUGGING +# define CopFILEAVx(c) (assert(CopFILEGV(c)), GvAV(CopFILEGV(c))) +# else +# define CopFILEAVx(c) (GvAV(CopFILEGV(c))) +# endif +# define CopFILE(c) (CopFILEGV(c) \ + ? GvNAME(CopFILEGV(c))+2 : NULL) # define CopSTASH(c) ((c)->cop_stash) # define CopSTASH_set(c,hv) ((c)->cop_stash = (hv)) # define CopFILE_free(c) (SvREFCNT_dec(CopFILEGV(c)),(CopFILEGV(c) = NULL)) #endif /* USE_ITHREADS */ -#define CopFILE_set(c,pv) CopFILEGV_set((c), gv_fetchfile(pv)) -#define CopFILE_setn(c,pv,l) CopFILEGV_set((c), gv_fetchfile_flags((pv),(l),0)) -#define CopFILESV(c) (CopFILEGV(c) ? GvSV(CopFILEGV(c)) : NULL) -#define CopFILEAV(c) (CopFILEGV(c) ? GvAV(CopFILEGV(c)) : NULL) -#define CopFILEAVx(c) (assert_(CopFILEGV(c)) GvAV(CopFILEGV(c))) -#define CopFILE(c) (CopFILEGV(c) \ - ? GvNAME(CopFILEGV(c))+2 : NULL) #define CopSTASHPV(c) (CopSTASH(c) ? HvNAME_get(CopSTASH(c)) : NULL) /* cop_stash is not refcounted */ #define CopSTASHPV_set(c,pv) CopSTASH_set((c), gv_stashpv(pv,GV_ADD)) |