I'm having a hard time with Apache::Session::DB_File, and I 
think I have it narrowed down to a small enough problem to 
ask about it.  I haven't given up on A::S::Postgres, I'm 
just trying to get things working with DB_File before I try 
to solve my other problem.

The one-sentence version of my question is: Is there a 
problem with tying a session twice during two different 
HeaderParserHandlers, as long as your doing the standard 
cleanup stuff (untie &| make_modified) in each?

The longer version:

I have managed to boil this problem down to as little code 
as possible for reproduction purposes.

I have two PerlHeaderParserHandlers listed in httpd.conf, 
to be run one after the other when a particular file is 
requested:

<Files handlertest.html>
    SetHandler  perl-script
    PerlHeaderParserHandler LocalSites::TestParser1 
LocalSites::TestParser2
</Files>

In the Real World, the first handler is a session manager, 
and the second handler is a login form processor.  The 
login form points to handlertest.html, a dummy file that no 
one should ever land on.

I have also added a couple of debug lines to 
Apache::Session::Lock::File, so I can track things:

In the beginning of acquire_read_lock:

warn "ARL: Write is: ".$self->{write}." Read is: 
".$self->{read}." Opened is: ".$self->{opened};

with similar lines in acquire_write_lock (AWL) and DESTROY.

The first HeaderParserHandler ties the session, puts the 
session id into pnotes, and unties.
----------------------------------------------------------------------
package LocalSites::TestParser1;
use strict;

use Apache::Constants qw(DECLINED);
use Apache::Session::DB_File;
use Apache::Log;

sub handler {
         my $r = shift;
         my $log = $r->server->log();
         my $session = $r->header_in('Cookie');
         $session =~ s/SESSION_ID=(\w*)/$1/;
         my %session = ();
         $log->error("TestParser1: tying session");
         tie %session, 'Apache::Session::DB_File',$session, 
{
             FileName=>'/www/data/sessions/sessions.db',
             LockDirectory=>'/var/lock/sessions',
         };
         $r->pnotes('SESSION_ID', %session->{_session_id});
         $log->error("TestParser1: untying session");
         untie(%session);
         $log->error("TestParser1: done");
         return DECLINED;
}
1;
__END__;
----------------------------------------------------------------------

The second handler, this one grabs the session id from 
pnotes, ties the session, modifies it, saves and unties:

----------------------------------------------------------------------
package LocalSites::TestParser2;
use strict;

use Apache::Constants qw(DECLINED);
use Apache::Session::DB_File;
use Apache::Log;

sub handler {
         my $r = shift;
         my $log = $r->server->log();
         my $session = $r->pnotes('SESSION_ID');
         my %session = ();
         $log->error("TestParser2: tying session");
         tie %session, 'Apache::Session::DB_File',$session, 
{
             FileName=>'/www/data/sessions/sessions.db',
             LockDirectory=>'/var/lock/sessions',
         };
         %session->{'AUTH'} = 1;
         tied(%session)->make_modified();
         $log->error("TestParser2: untying session");
         untie(%session);
         $log->error("TestParser2: done");
         return DECLINED;
}
1;
__END__;
----------------------------------------------------------------------

The error log output follows.  From the looks of it, the 
second module is failing to secure a write lock during the 
2nd handler because the 2nd handler already has it marked 
open.  The second handler does not exhibit this behavior 
when it's running by itself (unchanged except "my $session 
= undef;").

I'm not sure why I'm not seeing the DESTROY call from the 
first handler, but the read lock acquisition in the second 
indicates that the file is free for the plundering.

When both handlers are run, the process hangs where 
indicated below (acquiring the write lock).  Restarting 
Apache kills the process and results in the DESTROY calls 
below the indicated point.  Without a restart the process 
will sit indefinitely.

[Fri Jan 19 03:26:50 2001] [error] TestParser1: tying 
session
ARL: Write is: 0 Read is: 0 Opened is: 0 at 
/usr/lib/perl5/site_perl/5.005/Apache/Session/Lock/File.pm 
line 31.
        
Apache::Session::Lock::File::acquire_read_lock('Apache::Session::Lock::File=HASH(0x8670cf4)',
 
'Apache::Session::DB_File=HASH(0x8670c70)') called at 
/usr/lib/perl5/site_perl/5.005/Apache/Session.pm line 552
        Apache::Session::acquire_read_lock('Apache::Session::DB_File=HASH(0x8670c70)') 
called at /usr/lib/perl5/site_perl/5.005/Apache/Session.pm 
line 472
        Apache::Session::restore('Apache::Session::DB_File=HASH(0x8670c70)') 
called at /usr/lib/perl5/site_perl/5.005/Apache/Session.pm 
line 386
        Apache::Session::TIEHASH('Apache::Session::DB_File', 
'f4a0314ccd0c5e1b84e5670edd924983', 'HASH(0x85ec664)') 
called at 
/www/boygenius/libraries/LocalSites/TestParser1.pm line 15
        LocalSites::TestParser1::handler('Apache=SCALAR(0x85ec6d0)') 
called at /dev/null line 0
        eval {...} called at /dev/null line 0
[Fri Jan 19 03:26:50 2001] [error] TestParser1: untying 
session
[Fri Jan 19 03:26:50 2001] [error] TestParser1: done
[Fri Jan 19 03:26:50 2001] [error] TestParser2: tying 
session
ARL: Write is: 0 Read is: 0 Opened is: 0 at 
/usr/lib/perl5/site_perl/5.005/Apache/Session/Lock/File.pm 
line 31.
        
Apache::Session::Lock::File::acquire_read_lock('Apache::Session::Lock::File=HASH(0x8685488)',
 
'Apache::Session::DB_File=HASH(0x8685290)') called at 
/usr/lib/perl5/site_perl/5.005/Apache/Session.pm line 552
        Apache::Session::acquire_read_lock('Apache::Session::DB_File=HASH(0x8685290)') 
called at /usr/lib/perl5/site_perl/5.005/Apache/Session.pm 
line 472
        Apache::Session::restore('Apache::Session::DB_File=HASH(0x8685290)') 
called at /usr/lib/perl5/site_perl/5.005/Apache/Session.pm 
line 386
        Apache::Session::TIEHASH('Apache::Session::DB_File', 
'f4a0314ccd0c5e1b84e5670edd924983', 'HASH(0x85ec64c)') 
called at 
/www/boygenius/libraries/LocalSites/TestParser2.pm line 14
        LocalSites::TestParser2::handler('Apache=SCALAR(0x860e330)') 
called at /dev/null line 0
        eval {...} called at /dev/null line 0
AWL: Write is: 0 Read is: 1 Opened is: 1 at 
/usr/lib/perl5/site_perl/5.005/Apache/Session/Lock/File.pm 
line 52.
        
Apache::Session::Lock::File::acquire_write_lock('Apache::Session::Lock::File=HASH(0x8685488)',
 
'Apache::Session::DB_File=HASH(0x8685290)') called at 
/usr/lib/perl5/site_perl/5.005/Apache/Session.pm line 562
        
Apache::Session::acquire_write_lock('Apache::Session::DB_File=HASH(0x8685290)') 
called at /usr/lib/perl5/site_perl/5.005/Apache/Session.pm 
line 490
        Apache::Session::save('Apache::Session::DB_File=HASH(0x8685290)') 
called at /usr/lib/perl5/site_perl/5.005/Apache/Session.pm 
line 455
        Apache::Session::DESTROY('Apache::Session::DB_File=HASH(0x8685290)') 
called at /dev/null line 0
        eval {...} called at /dev/null line 0

 >>>>>>>>>>>>>>>>>It hangs here until 
restart<<<<<<<<<<<<<<<<
 >>>>Everything from here on is Apache cleaning 
up<<<<<<<<<<<

DESTROY: Open = 0 Write = 0 Read = 0 during global 
destruction.
        
Apache::Session::Lock::File::DESTROY('Apache::Session::Lock::File=HASH(0x8685488)') 
called at /dev/null line 0
        eval {...} called at /dev/null line 0
        Apache::Session::Lock::File::acquire_write_lock(undef, 
'Apache::Session::DB_File=HASH(0x8685290)') called at 
/usr/lib/perl5/site_perl/5.005/Apache/Session.pm line 562
        
Apache::Session::acquire_write_lock('Apache::Session::DB_File=HASH(0x8685290)') 
called at /usr/lib/perl5/site_perl/5.005/Apache/Session.pm 
line 490
        Apache::Session::save('Apache::Session::DB_File=HASH(0x8685290)') 
called at /usr/lib/perl5/site_perl/5.005/Apache/Session.pm 
line 455
        Apache::Session::DESTROY('Apache::Session::DB_File=HASH(0x8685290)') 
called at /dev/null line 0
        eval {...} called at /dev/null line 0
DESTROY: Open = 0 Write = 0 Read = 0 during global 
destruction.
        
Apache::Session::Lock::File::DESTROY('Apache::Session::Lock::File=HASH(0x8670cf4)') 
called at /dev/null line 0
        eval {...} called at /dev/null line 0
        Apache::Session::Lock::File::acquire_write_lock(undef, 
'Apache::Session::DB_File=HASH(0x8685290)') called at 
/usr/lib/perl5/site_perl/5.005/Apache/Session.pm line 562
        
Apache::Session::acquire_write_lock('Apache::Session::DB_File=HASH(0x8685290)') 
called at /usr/lib/perl5/site_perl/5.005/Apache/Session.pm 
line 490
        Apache::Session::save('Apache::Session::DB_File=HASH(0x8685290)') 
called at /usr/lib/perl5/site_perl/5.005/Apache/Session.pm 
line 455
        Apache::Session::DESTROY('Apache::Session::DB_File=HASH(0x8685290)') 
called at /dev/null line 0
        eval {...} called at /dev/null line 0


thanks!
Todd










Reply via email to