perl-modperl mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Torsten Foertsch <torsten.foert...@gmx.net>
Subject Re: [MP2] possible pnotes bug?
Date Thu, 16 Mar 2006 09:51:10 GMT
On Thursday 16 March 2006 00:39, Geoffrey Young wrote:
> >>>in order for $o to maintain it's internal state.  is that right?  if so,
> >>> I don't like that very much.
> >
> > It's not right. You are confusing scalars with references in that
> > example.
>
> ook, my bad - I thought the proposed "solution" was to always dereference
> pnotes behind the scenes, making the additional storage a requirement.
>
> but, just in case I'm not the only one confused, I'd propose a path like
> this...
>
>   o create some (many?) additional pnotes tests that exercise the different
> ways we think people will be using pnotes in almost all normal
> circumstances we can think of.  digging through CPAN might be a good idea.
>
>   o offer that any fix shouldn't break the tests

Here are some tests that cover your concerns so far:

package TestPn::pn;

use strict;
use warnings FATAL => 'all';

use Apache::Test;
use Apache::TestUtil;
use Apache2::RequestUtil;
use Apache2::Const -compile => 'OK';

{
    package _O;
    sub new {bless {}=>__PACKAGE__}
    sub member {$_[0]->{x}=$_[1] if @_>1; $_[0]->{x}}
}

sub handler {
    my $r = shift;

    Apache::Test::test_pm_refresh();
    plan $r, tests => 20;

    my $x;

    # pnotes as hash ref

    # this 1st set of tests are all ok, because $r->pnotes returns a normal
    # hash ref

    $x=1;
    $r->pnotes->{x}=$x;
    $x++;
    ok t_cmp $r->pnotes('x'), 1, q{hash ref1};
    ok t_cmp $r->pnotes->{x}, 1, q{hash ref2};
    delete $r->pnotes->{x};

    # pnotes method interface

    # these two fail

    $x=1;
    $r->pnotes(x=>$x);
    $x++;
    ok t_cmp $r->pnotes('x'), 1, q{method1};
    ok t_cmp $r->pnotes->{x}, 1, q{method2};
    delete $r->pnotes->{x};

    # pnotes as hash: storing and retrieving objects

    my $o1=_O->new;
    $o1->member(1);
    my $o2=_O->new;
    $o2->member(2);

    # check if the objects work properly

    ok t_cmp $o1->member, 1, q{o1 setup};
    ok t_cmp $o2->member, 2, q{o2 setup};

    # these tests succeed. they show normal object behavior.

    $r->pnotes->{o}=$o1;
    $o1->member(10);
    ok t_cmp $r->pnotes('o')->member, 10, q{hash ref obj 1};
    ok t_cmp $r->pnotes->{o}->member, 10, q{hash ref obj 2};

    $r->pnotes('o')->member(100);
    ok t_cmp $r->pnotes('o')->member, 100, q{hash ref obj 3};
    ok t_cmp $r->pnotes->{o}->member, 100, q{hash ref obj 4};

    # the following two succeed only because the hash ref interface
    # was used to assing $r->pnotes->{o}.

    $o1=$o2;
    ok t_cmp $r->pnotes('o')->member, 100, q{hash ref obj 5};
    ok t_cmp $r->pnotes->{o}->member, 100, q{hash ref obj 6};
    delete $r->pnotes->{o};

    # pnotes method interface: storing and retrieving objects

    $o1=_O->new;
    $o1->member(1);
    $o2=_O->new;
    $o2->member(2);

    ok t_cmp $o1->member, 1, q{o1 setup};
    ok t_cmp $o2->member, 2, q{o2 setup};

    $r->pnotes(o=>$o1);
    $o1->member(10);
    ok t_cmp $r->pnotes('o')->member, 10, q{method obj 1};
    ok t_cmp $r->pnotes->{o}->member, 10, q{method obj 2};

    $r->pnotes('o')->member(100);
    ok t_cmp $r->pnotes('o')->member, 100, q{method obj 3};
    ok t_cmp $r->pnotes->{o}->member, 100, q{method obj 4};

    # these two fail, because the assignment $o1=$o2 modifies $r->pnotes->{o}.

    $o1=$o2;
    ok t_cmp $r->pnotes('o')->member, 100, q{method obj 5};
    ok t_cmp $r->pnotes->{o}->member, 100, q{method obj 6};
    delete $r->pnotes->{o};

    Apache2::Const::OK;
}

1;


The patch is IMO really simple:

In xs/Apache2/ConnectionUtil/Apache2__ConnectionUtil.h and
xs/Apache2/RequestUtil/Apache2__RequestUtil.h

         if (val) {
             retval = *hv_store(ccfg->pnotes, k, len,
-                               SvREFCNT_inc(val), 0);
+                               newSVsv(val), 0);
         }
         else if (hv_exists(ccfg->pnotes, k, len)) {
             retval = *hv_fetch(ccfg->pnotes, k, len, FALSE);


The attached patch was made a few days ago. It applies to r384596 with the
connection-pnotes patch applied before. All tests succeed.

Torsten

Mime
View raw message