diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2eaada7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/DB_File-1.830.tar.gz diff --git a/.perl-DB_File.metadata b/.perl-DB_File.metadata new file mode 100644 index 0000000..ba2edcb --- /dev/null +++ b/.perl-DB_File.metadata @@ -0,0 +1 @@ +dbd03136c8f80397aaa03e8edec82bec2321f2fa SOURCES/DB_File-1.830.tar.gz diff --git a/SOURCES/DB_File-1.831-Destroy-DB_File-objects-only-from-original-thread-co.patch b/SOURCES/DB_File-1.831-Destroy-DB_File-objects-only-from-original-thread-co.patch new file mode 100644 index 0000000..3a0974b --- /dev/null +++ b/SOURCES/DB_File-1.831-Destroy-DB_File-objects-only-from-original-thread-co.patch @@ -0,0 +1,180 @@ +From d4499d6a6f8007df03fe5292aab4ba0367499dd0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= +Date: Tue, 10 Jun 2014 14:28:09 +0200 +Subject: [PATCH] Destroy DB_File objects only from original thread context +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This patch fixes a crash when destroing a hash tied to a DB_File +database after spawning a thread: + +use Fcntl; +use DB_File; +use threads; +tie(my %dbtest, 'DB_File', "test.db", O_RDWR|O_CREAT, 0666); +threads->new(sub {})->join; + +This crashed or paniced depending on how perl was configured. + +Closes RT#61912. + +Signed-off-by: Petr Písař +--- + DB_File.xs | 50 +++++++++++++++++++++++++++++++------------------- + MANIFEST | 1 + + t/db-threads.t | 46 ++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 78 insertions(+), 19 deletions(-) + create mode 100644 t/db-threads.t + +diff --git a/DB_File.xs b/DB_File.xs +index 679c416..762f4ed 100755 +--- a/DB_File.xs ++++ b/DB_File.xs +@@ -397,6 +397,7 @@ typedef union INFO { + + typedef struct { + DBTYPE type ; ++ tTHX owner ; + DB * dbp ; + SV * compare ; + bool in_compare ; +@@ -983,6 +984,7 @@ SV * sv ; + name, flags, mode, sv == NULL) ; + #endif + Zero(RETVAL, 1, DB_File_type) ; ++ RETVAL->owner = aTHX; + + /* Default to HASH */ + RETVAL->filtering = 0 ; +@@ -1255,6 +1257,7 @@ SV * sv ; + + /* printf("In ParseOpenInfo name=[%s] flags=[%d] mode = [%d]\n", name, flags, mode) ; */ + Zero(RETVAL, 1, DB_File_type) ; ++ RETVAL->owner = aTHX; + + /* Default to HASH */ + RETVAL->filtering = 0 ; +@@ -1571,27 +1574,36 @@ db_DESTROY(db) + INIT: + CurrentDB = db ; + Trace(("DESTROY %p\n", db)); +- CLEANUP: +- Trace(("DESTROY %p done\n", db)); +- if (db->hash) +- SvREFCNT_dec(db->hash) ; +- if (db->compare) +- SvREFCNT_dec(db->compare) ; +- if (db->prefix) +- SvREFCNT_dec(db->prefix) ; +- if (db->filter_fetch_key) +- SvREFCNT_dec(db->filter_fetch_key) ; +- if (db->filter_store_key) +- SvREFCNT_dec(db->filter_store_key) ; +- if (db->filter_fetch_value) +- SvREFCNT_dec(db->filter_fetch_value) ; +- if (db->filter_store_value) +- SvREFCNT_dec(db->filter_store_value) ; +- safefree(db) ; ++ CODE: ++ RETVAL = 0; ++ if (db && db->owner == aTHX) { ++ RETVAL = db_DESTROY(db); + #ifdef DB_VERSION_MAJOR +- if (RETVAL > 0) +- RETVAL = -1 ; ++ if (RETVAL > 0) ++ RETVAL = -1 ; + #endif ++ } ++ OUTPUT: ++ RETVAL ++ CLEANUP: ++ Trace(("DESTROY %p done\n", db)); ++ if (db && db->owner == aTHX) { ++ if (db->hash) ++ SvREFCNT_dec(db->hash) ; ++ if (db->compare) ++ SvREFCNT_dec(db->compare) ; ++ if (db->prefix) ++ SvREFCNT_dec(db->prefix) ; ++ if (db->filter_fetch_key) ++ SvREFCNT_dec(db->filter_fetch_key) ; ++ if (db->filter_store_key) ++ SvREFCNT_dec(db->filter_store_key) ; ++ if (db->filter_fetch_value) ++ SvREFCNT_dec(db->filter_fetch_value) ; ++ if (db->filter_store_value) ++ SvREFCNT_dec(db->filter_store_value) ; ++ safefree(db) ; ++ } + + + int +diff --git a/MANIFEST b/MANIFEST +index e460e81..47f43f7 100644 +--- a/MANIFEST ++++ b/MANIFEST +@@ -27,6 +27,7 @@ t/db-btree.t + t/db-hash.t + t/db-recno.t + t/pod.t ++t/db-threads.t + typemap + version.c + META.yml Module meta-data (added by MakeMaker) +diff --git a/t/db-threads.t b/t/db-threads.t +new file mode 100644 +index 0000000..b9f69b6 +--- /dev/null ++++ b/t/db-threads.t +@@ -0,0 +1,46 @@ ++#!./perl ++ ++use warnings; ++use strict; ++use Config; ++use Fcntl; ++use Test::More; ++use DB_File; ++ ++if (-d "lib" && -f "TEST") { ++ if ($Config{'extensions'} !~ /\bDB_File\b/ ) { ++ plan skip_all => 'DB_File was not built'; ++ } ++} ++plan skip_all => 'Threads are disabled' ++ unless $Config{usethreads}; ++ ++plan tests => 7; ++ ++# Check DBM back-ends do not destroy objects from then-spawned threads. ++# RT#61912. ++use_ok('threads'); ++ ++my %h; ++unlink ; ++ ++my $db = tie %h, 'DB_File', 'threads', O_RDWR|O_CREAT, 0640; ++isa_ok($db, 'DB_File'); ++ ++for (1 .. 2) { ++ ok(threads->create( ++ sub { ++ $SIG{'__WARN__'} = sub { fail(shift) }; # debugging perl panics ++ # report it by spurious TAP line ++ 1; ++ }), "Thread $_ created"); ++} ++for (threads->list) { ++ is($_->join, 1, "A thread exited successfully"); ++} ++ ++pass("Tied object survived exiting threads"); ++ ++undef $db; ++untie %h; ++unlink ; +-- +1.9.3 + diff --git a/SPECS/perl-DB_File.spec b/SPECS/perl-DB_File.spec new file mode 100644 index 0000000..97245f5 --- /dev/null +++ b/SPECS/perl-DB_File.spec @@ -0,0 +1,97 @@ +Name: perl-DB_File +Version: 1.830 +Release: 6%{?dist} +Summary: Perl5 access to Berkeley DB version 1.x +License: GPL+ or Artistic +Group: Development/Libraries +URL: http://search.cpan.org/dist/DB_File/ +Source0: http://www.cpan.org/authors/id/P/PM/PMQS/DB_File-%{version}.tar.gz +# Destroy DB_File objects only from original thread context, bug #1107728, +# CPAN RT#96357 +Patch0: DB_File-1.831-Destroy-DB_File-objects-only-from-original-thread-co.patch +BuildRequires: libdb-devel +BuildRequires: perl +BuildRequires: perl(Config) +BuildRequires: perl(ExtUtils::Constant) +BuildRequires: perl(ExtUtils::MakeMaker) >= 5.16 +# File::Copy not needed if ExtUtils::Constant is available +BuildRequires: perl(strict) +# Run-time: +BuildRequires: perl(Carp) +# DynaLoader not needed if XSLoader is available +BuildRequires: perl(Exporter) +BuildRequires: perl(Fcntl) +BuildRequires: perl(File::Spec) +BuildRequires: perl(Tie::Hash) +BuildRequires: perl(warnings) +BuildRequires: perl(XSLoader) +# Tests: +BuildRequires: perl(Symbol) +BuildRequires: perl(Test::More) +BuildRequires: perl(threads) +%if !%{defined perl_bootstrap} +# Optional tests: +# Data::Dumper not useful +BuildRequires: perl(Test::Pod) >= 1.00 +%endif +Requires: perl(:MODULE_COMPAT_%(eval "`perl -V:version`"; echo $version)) +Requires: perl(Fcntl) +Requires: perl(XSLoader) + +%{?perl_default_filter} + +%description +DB_File is a module which allows Perl programs to make use of the facilities +provided by Berkeley DB version 1.x (if you have a newer version of DB, you +will be limited to functionality provided by interface of version 1.x). The +interface defined here mirrors the Berkeley DB interface closely. + +%prep +%setup -q -n DB_File-%{version} +%patch0 -p1 +find -type f -exec chmod -x {} + +%fix_shbang_line dbinfo + +%build +perl Makefile.PL INSTALLDIRS=vendor OPTIMIZE="$RPM_OPT_FLAGS" +make %{?_smp_mflags} + +%install +make pure_install DESTDIR=$RPM_BUILD_ROOT +find $RPM_BUILD_ROOT -type f -name .packlist -exec rm -f {} \; +find $RPM_BUILD_ROOT -type f -name '*.bs' -size 0 -exec rm -f {} \; +%{_fixperms} $RPM_BUILD_ROOT/* + +%check +make test + +%files +%doc Changes dbinfo README +%{perl_vendorarch}/auto/* +%{perl_vendorarch}/DB_File* +%{_mandir}/man3/* + +%changelog +* Fri Aug 08 2014 Petr Pisar - 1.830-6 +- Build-require Test::More always because of the new thread tests + +* Thu Aug 07 2014 Petr Pisar - 1.830-5 +- Initialize db_DESTROY return variable (bug #1107728) + +* Fri Jun 13 2014 Petr Pisar - 1.830-4 +- Destroy DB_File objects only from original thread context (bug #1107728) + +* Fri Jan 24 2014 Daniel Mach - 1.830-3 +- Mass rebuild 2014-01-24 + +* Fri Dec 27 2013 Daniel Mach - 1.830-2 +- Mass rebuild 2013-12-27 + +* Mon Nov 04 2013 Petr Pisar - 1.830-1 +- 1.830 bump (bug #1026266) + +* Thu May 09 2013 Petr Pisar - 1.828-1 +- 1.828 bump + +* Thu Mar 21 2013 Petr Pisar 1.827-1 +- Specfile autogenerated by cpanspec 1.78.