Hello,

I want to implement a singleton pattern on my logger module. During
initial instantiation, the logger module is seeded with some
information (ie. transactionId) and creates some (ie. requestTime).
What I want is for the logger object to be instantiated (if needed)
and/or retrieved from the Logger::getInstance() method for each HTTP
request...basically I don't want to have to pass the object around but
instead return a the reference to the instance when I need it.

First, some info about my environment: mp2 on RHEL. The prefork MPM
is in use but I explicitly turned off worker as the existing
application I will be working against is not thread safe.

What I am running into is that the new instance is created for each
process and is accessible throughout the request as intended.
Unfortunately, what I am also noticing is that when the process is
reused by Apache, the previous logger instance still exists and is
pulled back by reference and therefore have incorrect parameters
(since the transactionID and requestTime has changed). I believe this
is by design because it obviously would give a decent performance
boost under situations where this is OK. However, this is not one of
these times =).

I thought of two solutions, both of which don't seem a great answer.
First was to explicitly DESTROY the logger object when I was done with
the request (which would work, since I have a controller/router
managing the request). however, if something goes wrong I can't be
sure the logger would be destroyed. Second was to create a factory
method in addition to the traditional singleton static method to
explicitly create a new instance and overwrite the existing. I think
this would work with my environment (only prefork MPM) but it smells
as if it wouldn't be thread safe - I imagine a spawned threat would
overwrite and corrupt multiple threads on a process. I included
psudo-code of the second theory below so you can pretty much see what
I am doing.

Is there any way to have a MPM-safe (specifically thread-safe)
singleton pattern?

P.S. For those of you who noticed, even though the app I'm eventually
going to integrate with is not thread safe, I am building a SOA
mid-tier that I wish to release open source and personally reuse, so I
want it to be thread safe. =)


Thanks,

Steve

psudo code:

package Logger;

my $this; # singleton instance

sub getInstance { my ( $self, $transId ) = @_;
unless (defined $this) {
$self->createNewInstance($transId);
}
return $this;
}

sub createNewInstance { my ( $self, $transId ) = @_;
my $vars = {'transId' => $transId};
$this = bless $vars, $self;

$this->_getRequestDate();

return $this;
}
1;