Boost logo

Boost :

From: Jason Hise (chaos_at_[hidden])
Date: 2005-02-06 13:36:52


Recent changes:

* The dependency lifetime now works by using the pointers themselves as
dependencies, and using lazy creation to determine whether creation of
the pointer or dereferencing of the pointer creates the instance. Using
the pointer instead of a separate dependency class allows the lifetime
to achieve a consistent interface with the other lifetime policies.

* All lifetime policies now work uniformly for Singletons, Multitons,
and potentially any Somethingtons that an end user might choose to
implement (HashedMultiton, TwoKeyedMultiton, etc...). The only caveat
is that the Multiton instance holder (a singleton used in the
implementation of the multiton), must use a leaky lifetime. If any
other type of lifetime is used, combining the longevity lifetime policy
with the multiton ends up being disastrous. If the OS cleans up leaked
memory when the program exits, this should not be a problem. Even so, I
would like to find a better solution if possible.

Because I have no experience with multi threading, I need someone to
verify that I am locking in all of the right places, and that any
singleton/multiton operations that need to be thread safe actually are
thread safe. A sample test program is provided below, whose lifetime
policies can be easily edited to verify order of creation and
destruction in all circumstances.

I am fairly confident that my singleton library is now complete. What
are the next steps to take in adding it to Boost?

-Jason

// Sample Program

#include <sstream>
#include <fstream>

#include "../Include/StaticAllocator.h"
#include "../Include/MallocAllocator.h"
#include "../Include/LongevityLifetime.h"
#include "../Include/Singleton.h"
#include "../Include/Multiton.h"

using namespace boost::singleton;
using std::stringstream;
using std::ofstream;

class TestLog : public Singleton < TestLog, LongevityLifetime < TestLog,
10 > >
{
private:
    ofstream out;

protected:
    TestLog ( ) : out ( "log.dat" )
    {
        out << "Test log created.\n";
    }

    ~ TestLog ( )
    {
        out << "Test log destroyed.\n";
        out.close ( );
    }

public:
    void Write ( const char * msg )
    {
        out << msg;
    }
};

class A : public Multiton < int, A, LongevityLifetime < A, 5 > >
{
private:
    TestLog :: Pointer log;

protected:
    A ( )
    {
        log->Write ( "A created.\n" );
    }

    ~ A ( )
    {
        log->Write ( "A destroyed.\n" );
    }
};

// lifetime longevity higher than A, to verify that even though A is
created first, it is still destroyed after B
class B : public Singleton < B, LongevityLifetime < B, 7 > >
{
private:
    TestLog :: Pointer log;
    A :: Pointer a1;
    A :: Pointer a2;
    A :: Pointer a3;

protected:
    B ( ) : a1 ( 0 ), a2 ( 1 ), a3 ( 1 )
    {
        log->Write ( "B created.\n" );
    }

    ~ B ( )
    {
        log->Write ( "B destroyed.\n" );
    }

public:
    void foo ( )
    {
        log->Write ( "foo called.\n" );
    }
};

int main ( )
{
    B::Pointer ptr;
    ptr->foo ( );
}


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk