use new singleton lifetime policies
git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@343 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
parent
10cdcd9d59
commit
6c8b1660b4
1 changed files with 172 additions and 91 deletions
|
@ -1,6 +1,7 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// The Loki Library
|
// The Loki Library
|
||||||
// Copyright (c) 2005 Richard Sposato
|
// Copyright (c) 2005 Richard Sposato
|
||||||
|
// Copyright (c) 2005 Peter Kümmel
|
||||||
// Permission to use, copy, modify, distribute and sell this software for any
|
// Permission to use, copy, modify, distribute and sell this software for any
|
||||||
// purpose is hereby granted without fee, provided that the above copyright
|
// purpose is hereby granted without fee, provided that the above copyright
|
||||||
// notice appear in all copies and that both that copyright notice and this
|
// notice appear in all copies and that both that copyright notice and this
|
||||||
|
@ -17,30 +18,122 @@
|
||||||
#include "../../include/loki/Singleton.h"
|
#include "../../include/loki/Singleton.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
// define DO_EXTRA_LOKI_TESTS in src/SmallObj.cpp to get
|
||||||
|
// a message when a SmallObject is created/deleted.
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// FollowIntoDeath policy
|
||||||
|
//
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
typedef Loki::SmallValueObject< LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL,
|
typedef Loki::SmallValueObject< LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL,
|
||||||
LOKI_DEFAULT_CHUNK_SIZE, LOKI_MAX_SMALL_OBJECT_SIZE,
|
LOKI_DEFAULT_CHUNK_SIZE, LOKI_MAX_SMALL_OBJECT_SIZE,
|
||||||
LOKI_DEFAULT_OBJECT_ALIGNMENT, Loki::SingletonWithLongevity >
|
LOKI_DEFAULT_OBJECT_ALIGNMENT,
|
||||||
LongLivedObject;
|
Loki::FollowIntoDeath::With<Loki::DefaultLifetime>::AsMasterLifetime // this is default
|
||||||
|
>
|
||||||
|
MasterObject;
|
||||||
|
|
||||||
|
class FollowerSingleton : public MasterObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef Loki::SingletonHolder< FollowerSingleton, Loki::CreateUsingNew,
|
||||||
|
Loki::FollowIntoDeath::AfterMaster<FollowerSingleton::ObjAllocatorSingleton>::IsDestroyed,
|
||||||
|
LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL >
|
||||||
|
MySmallSingleton;
|
||||||
|
|
||||||
|
/// Returns reference to the singleton.
|
||||||
|
inline static FollowerSingleton & Instance( void )
|
||||||
|
{
|
||||||
|
return MySmallSingleton::Instance();
|
||||||
|
}
|
||||||
|
|
||||||
|
FollowerSingleton( void )
|
||||||
|
{
|
||||||
|
cout << "FollowerSingleton created" << endl;
|
||||||
|
}
|
||||||
|
~FollowerSingleton( void )
|
||||||
|
{
|
||||||
|
cout << "~FollowerSingleton" << endl;
|
||||||
|
}
|
||||||
|
void DoThat( void )
|
||||||
|
{
|
||||||
|
cout << "FollowerSingleton::DoThat" << endl << endl;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
char m_stuff[ 16 ];
|
||||||
|
};
|
||||||
|
|
||||||
typedef Loki::SmallValueObject< LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL,
|
|
||||||
LOKI_DEFAULT_CHUNK_SIZE, LOKI_MAX_SMALL_OBJECT_SIZE,
|
|
||||||
LOKI_DEFAULT_OBJECT_ALIGNMENT, Loki::NoDestroy >
|
|
||||||
ImmortalObject;
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// DieOrder policy
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
typedef Loki::SmallValueObject< LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL,
|
||||||
|
LOKI_DEFAULT_CHUNK_SIZE, LOKI_MAX_SMALL_OBJECT_SIZE,
|
||||||
|
LOKI_DEFAULT_OBJECT_ALIGNMENT,
|
||||||
|
Loki::DieOrder::Last
|
||||||
|
>
|
||||||
|
DieLastObject;
|
||||||
|
|
||||||
|
class DieFirstSingleton : public DieLastObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef Loki::SingletonHolder< DieFirstSingleton, Loki::CreateUsingNew,
|
||||||
|
Loki::DieOrder::First,
|
||||||
|
LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL >
|
||||||
|
MySmallSingleton;
|
||||||
|
|
||||||
|
/// Returns reference to the singleton.
|
||||||
|
inline static DieFirstSingleton & Instance( void )
|
||||||
|
{
|
||||||
|
return MySmallSingleton::Instance();
|
||||||
|
}
|
||||||
|
|
||||||
|
DieFirstSingleton( void )
|
||||||
|
{
|
||||||
|
cout << "DieFirstSingleton created" << endl;
|
||||||
|
}
|
||||||
|
~DieFirstSingleton( void )
|
||||||
|
{
|
||||||
|
cout << "~DieFirstSingleton" << endl;
|
||||||
|
}
|
||||||
|
void DoThat( void )
|
||||||
|
{
|
||||||
|
cout << "DieFirstSingleton::DoThat" << endl << endl;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
char m_stuff[ 16 ];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// SingletonWithLongevity policy
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
typedef Loki::SmallValueObject< LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL,
|
||||||
|
LOKI_DEFAULT_CHUNK_SIZE, LOKI_MAX_SMALL_OBJECT_SIZE,
|
||||||
|
LOKI_DEFAULT_OBJECT_ALIGNMENT,
|
||||||
|
Loki::SingletonWithLongevity
|
||||||
|
>
|
||||||
|
LongLivedObject;
|
||||||
|
|
||||||
class LongLivedSingleton : public LongLivedObject
|
class LongLivedSingleton : public LongLivedObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef Loki::SingletonHolder< LongLivedSingleton, Loki::CreateUsingNew,
|
typedef Loki::SingletonHolder< LongLivedSingleton, Loki::CreateUsingNew,
|
||||||
Loki::SingletonWithLongevity, LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL >
|
Loki::SingletonWithLongevity,
|
||||||
|
LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL >
|
||||||
MySmallSingleton;
|
MySmallSingleton;
|
||||||
|
|
||||||
/// Returns reference to the singleton.
|
/// Returns reference to the singleton.
|
||||||
|
@ -51,7 +144,7 @@ public:
|
||||||
|
|
||||||
LongLivedSingleton( void )
|
LongLivedSingleton( void )
|
||||||
{
|
{
|
||||||
cout << "LongLivedSingleton" << endl;
|
cout << "LongLivedSingleton created" << endl;
|
||||||
}
|
}
|
||||||
~LongLivedSingleton( void )
|
~LongLivedSingleton( void )
|
||||||
{
|
{
|
||||||
|
@ -59,119 +152,107 @@ public:
|
||||||
}
|
}
|
||||||
void DoThat( void )
|
void DoThat( void )
|
||||||
{
|
{
|
||||||
cout << "LongLivedSingleton::DoThat" << endl;
|
cout << "LongLivedSingleton::DoThat" << endl << endl;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
char m_stuff[ 16 ];
|
char m_stuff[ 16 ];
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
inline unsigned int GetLongevity( LongLivedSingleton * )
|
inline unsigned int GetLongevity( LongLivedSingleton * )
|
||||||
{
|
{
|
||||||
/// @note Must return a longevity level lower than the one in SmallObj.h.
|
/// @note Must return a longevity level lower than the one in SmallObj.h.
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
class ImmortalSingleton : public ImmortalObject
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef Loki::SingletonHolder< ImmortalSingleton, Loki::CreateUsingNew,
|
|
||||||
Loki::NoDestroy, LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL >
|
|
||||||
MySmallSingleton;
|
|
||||||
|
|
||||||
/// Returns reference to the singleton.
|
|
||||||
inline static ImmortalSingleton & Instance( void )
|
|
||||||
{
|
|
||||||
return MySmallSingleton::Instance();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImmortalSingleton( void )
|
|
||||||
{
|
|
||||||
cout << "ImmortalSingleton" << endl;
|
|
||||||
}
|
|
||||||
~ImmortalSingleton( void )
|
|
||||||
{
|
|
||||||
cout << "~ImmortalSingleton destructor should never get called!" << endl;
|
|
||||||
}
|
|
||||||
void DoThat( void )
|
|
||||||
{
|
|
||||||
cout << "ImmortalSingleton::DoThat" << endl;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
char m_stuff[ 16 ];
|
|
||||||
};
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
class MortalSingleton : public ImmortalObject
|
// detect memory leaks on MSVC Ide
|
||||||
{
|
//
|
||||||
public:
|
|
||||||
|
|
||||||
typedef Loki::SingletonHolder< MortalSingleton, Loki::CreateUsingNew,
|
|
||||||
Loki::SingletonWithLongevity, LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL >
|
|
||||||
MySmallSingleton;
|
|
||||||
|
|
||||||
/// Returns reference to the singleton.
|
|
||||||
inline static MortalSingleton & Instance( void )
|
|
||||||
{
|
|
||||||
return MySmallSingleton::Instance();
|
|
||||||
}
|
|
||||||
|
|
||||||
MortalSingleton( void )
|
|
||||||
{
|
|
||||||
cout << "MortalSingleton" << endl;
|
|
||||||
}
|
|
||||||
~MortalSingleton( void )
|
|
||||||
{
|
|
||||||
cout << "~MortalSingleton" << endl;
|
|
||||||
}
|
|
||||||
void DoThat( void )
|
|
||||||
{
|
|
||||||
cout << "MortalSingleton::DoThat" << endl;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
char m_stuff[ 16 ];
|
|
||||||
};
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
inline unsigned int GetLongevity( MortalSingleton * )
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
|
#include <crtdbg.h>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
void heap_debug()
|
||||||
{
|
{
|
||||||
/// @note Must return a longevity level lower than the one in SmallObj.h.
|
int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
|
||||||
return 1;
|
|
||||||
|
// Turn on leak-checking bit
|
||||||
|
tmpFlag |= _CRTDBG_LEAK_CHECK_DF;
|
||||||
|
|
||||||
|
//tmpFlag |= _CRTDBG_CHECK_MasterLWMasterYS_DF;
|
||||||
|
|
||||||
|
// Turn off CRT block checking bit
|
||||||
|
tmpFlag &= ~_CRTDBG_CHECK_CRT_DF;
|
||||||
|
|
||||||
|
// Set flag to the new value
|
||||||
|
_CrtSetDbgFlag( tmpFlag );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// main
|
||||||
|
//
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
cout << "This program tests the three recommended combinations of singleton" << endl
|
|
||||||
<< "lifetime policies for Loki's Small-Object Allocator and singleton" << endl
|
#ifdef _MSC_VER
|
||||||
<< "objects that are derived from SmallObject or SmallValueObject." << endl << endl
|
heap_debug();
|
||||||
<< "Those 3 recommended combinations are:" << endl
|
#endif
|
||||||
<< "\t1. Both SmallObject and derived Singleton use NoDestroy policy." << endl
|
|
||||||
<< "\t This is tested by the ImmortalSingleton class." << endl
|
cout << endl
|
||||||
<< "\t2. Both use SingletonWithLongevity policy." << endl
|
<< "This program tests the three recommended lifetime policies for Loki's " << endl
|
||||||
<< "\t This is tested by the LongLivedSingleton class." << endl
|
<< "Small-Object Allocator and singleton objects that are derived " << endl
|
||||||
<< "\t3. SmallObject has NoDestroy policy but the derived Singleton has" << endl
|
<< "from SmallObject or SmallValueObject." << endl
|
||||||
<< "\t SingletonWithLongevity policy." << endl
|
<< endl
|
||||||
<< "\t This is tested by the MortalSingleton class." << endl << endl
|
<< "Use one of the following lifetime policies" << endl
|
||||||
<< "If this program executes without crashing or asserting at exit time," << endl
|
<< "to manage the lifetime dependency:" << endl
|
||||||
<< "then all 3 combinations work." << endl << endl;
|
<< endl
|
||||||
MortalSingleton::Instance().DoThat();
|
<< "1. FollowIntoDeath:" << endl
|
||||||
|
<< " SmallObject has " << endl
|
||||||
|
<< " FollowIntoDeath::With<LIFETIME>::AsMasterLiftime policy" << endl
|
||||||
|
<< " and the derived Singleton has " << endl
|
||||||
|
<< " FollowIntoDeath::After<MASTERSINGLETON>::IsDestroyed policy" << endl
|
||||||
|
<< " This is tested by the FollowerSingleton class." << endl
|
||||||
|
<< endl
|
||||||
|
<< "2. DieOrder:" << endl
|
||||||
|
<< " SmallObject has " << endl
|
||||||
|
<< " DieOrder::Last policy " << endl
|
||||||
|
<< " and the derived Singleton has " << endl
|
||||||
|
<< " DieOrder::First" << endl
|
||||||
|
<< " This is tested by the DieOrderSingleton class." << endl
|
||||||
|
<< endl
|
||||||
|
<< "3. Both SmallObject and derived Singleton use SingletonWithLongevity policy." << endl
|
||||||
|
<< " This is tested by the LongLivedSingleton class." << endl
|
||||||
|
<< endl << endl
|
||||||
|
<< "If this program executes without crashing or asserting" << endl
|
||||||
|
<< " at exit time, then all 3 policies work." << endl << endl;
|
||||||
|
|
||||||
|
FollowerSingleton::Instance().DoThat();
|
||||||
|
DieFirstSingleton::Instance().DoThat();
|
||||||
LongLivedSingleton::Instance().DoThat();
|
LongLivedSingleton::Instance().DoThat();
|
||||||
ImmortalSingleton::Instance().DoThat();
|
|
||||||
system("PAUSE");
|
system("PAUSE");
|
||||||
|
|
||||||
|
cout << endl<< endl << "now leaving main" << endl << endl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// $Log$
|
// $Log$
|
||||||
|
// Revision 1.4 2005/11/02 13:58:18 syntheticpp
|
||||||
|
// use new singleton lifetime policies
|
||||||
|
//
|
||||||
// Revision 1.3 2005/10/30 14:03:23 syntheticpp
|
// Revision 1.3 2005/10/30 14:03:23 syntheticpp
|
||||||
// replace tabs space
|
// replace tabs space
|
||||||
//
|
//
|
||||||
|
|
Loading…
Add table
Reference in a new issue