Mailing List Archive

Apache::Session, tie and references to hashes
hi all

the problem with Apache::Session is a simple one and has more to do with tie

consider the following code

tie %session, 'Apache::Session::File', undef, {Directory => "/tmp/sessions"};

$sid = $session{_session_id};

%session{data} = { data => deadbeef };

$session{data}->{data} = "fatmice";

untie %session;

tie %session, 'Apache::Session::File', $sid, {Directory => "/tmp/sessions"};

print $session{data}->{data};

exit;

Now instead of getting "fatmice" we get "deadbeef";

This is due to the fact that Apache::Session only saves the %session if it has been modified. Which it has,
but because $session{data} contains a reference to an anonymous hash, the memory location doesn't chance
even though the data within that memory location has.

The only solution(s) is to
a) increment a variable that is not a reference to force a change or
b) add an option to Apache::Session that 'forces' a write everytime the hash is untied - i believe this is the best option and looking at the code very simple to implement.



--

Adam Cassar
Senior Web Developer
___________________________________________
NetRegistry http://www.netregistry.com.au
Tel: +61 2 9699 6099 | Fax: +61 2 9699 6088
PO Box 270 Broadway NSW 2007 Australia
Re: Apache::Session, tie and references to hashes [ In reply to ]
Adam Cassar wrote:
>
> hi all
>
> the problem with Apache::Session is a simple one and has more to do with tie
>
> consider the following code
>
> tie %session, 'Apache::Session::File', undef, {Directory => "/tmp/sessions"};
>
> $sid = $session{_session_id};
>
> %session{data} = { data => deadbeef };
>
> $session{data}->{data} = "fatmice";
>
> untie %session;
>
> tie %session, 'Apache::Session::File', $sid, {Directory => "/tmp/sessions"};
>
> print $session{data}->{data};
>
> exit;
>
> Now instead of getting "fatmice" we get "deadbeef";
>
> This is due to the fact that Apache::Session only saves the %session if it has been modified. Which it has,
> but because $session{data} contains a reference to an anonymous hash, the memory location doesn't chance
> even though the data within that memory location has.
>
> The only solution(s) is to
> a) increment a variable that is not a reference to force a change or
> b) add an option to Apache::Session that 'forces' a write everytime the hash is untied - i believe this is the best option and looking at the code very simple to implement.

You forgot the correct solution:

c) Use the object interface thoughtfully provided by the author to force
a write. e.g. tied(%session)->make_modified();
d) Use the object interface thoughtfully provided by the author to force
a write. e.g. tied(%session)->{object_store}->update(tied(%session));

You pick :)

Cheers,
Jeffrey