Ron Kass
2007-Oct-19 01:16 UTC
[Xapian-discuss] Perl threads and Xapian - incompatibility?
Try the following code: #!/usr/bin/perl -W use strict; use threads; use Search::Xapian; my $Xapian_DB Search::Xapian::WritableDatabase->new("test",Search::Xapian::DB_CREATE_OR_OPEN); my $Thr1 = threads->create(sub{print "1\n"}); my $Thr2 = threads->create(sub{print "2\n"}); my $Thr3 = threads->create(sub{print "3\n"}); print "joins #1\n"; $Thr1->join; print "joins #2\n"; $Thr2->join; print "joins #3\n"; $Thr3->join; here is what we get: # perl tst.pl joins #1 1 2 3 joins #2 Segmentation fault Setting: Xapian 1.0.3 (flint backend), perl 5.8.8, threads 1.67 Notice that ALL it takes is an open Xapian DB. It doesn't have to be a writable one btw. You can replace the line with a [my $Xapian_DB = Search::Xapian::Database->new("test");] if you already have a test database in place. Same error. Notice that the bug happens on the SECOND call to a thread instance. It can be a call to the detach method [->detach();].. same error. Anyone saw this bug? Any patches for that one? Best regards, Ron
Olly Betts
2007-Oct-19 04:10 UTC
[Xapian-discuss] Perl threads and Xapian - incompatibility?
On Fri, Oct 19, 2007 at 02:15:52AM +0200, Ron Kass wrote:> You can replace the line with a [my $Xapian_DB = > Search::Xapian::Database->new("test");] if you already have a test > database in place. Same error.I used this variant.> Notice that the bug happens on the SECOND call to a thread instance. It > can be a call to the detach method [->detach();].. same error.If you move the creation of the database down a line or two, the SEGV happens on the third thread. If you move it down below the creation of the threads, the code runs to completion. This seems a reasonable workaround as you can't share a Xapian object between threads anyway. Now `perldoc threads' says that the Perl threads module starts a new interpreter instance for each thread, and that variables aren't shared. However, adding a printf to the XS wrapper for the Database destructor shows it is called when each thread terminates! If I add `print "$Xapian_DB\n"' to each thread routine, the output is: 1 Search::Xapian::Database=SCALAR(0x954a70) joins #1 2 Search::Xapian::Database=SCALAR(0xaffcd0) Database dtor called joins #2 Database dtor called Segmentation fault (core dumped) So it looks like the new interpreter for each thread makes a new Perl Search::Xapian::Database object, but wrapped around the same C++ Xapian::Database object inside. That's never going to work well! I've no idea how to fix this (or if it is fixable even), but you have a workaround. Cheers, Olly