/// \file This file illustrates the two template classes LockedSingleton and LockedSingletonWithDetor. /// /// This file illustrates the two template classes LockedSingleton and LockedSingletonWithDetor. 3 classes are declared locally to illustrate the uses of the template class. The class singleton_hello is a singleton class, which also has a destructor, destroy_instance. The class ThreadSpeak uses the template class LockedSingleton< singleton_hello> to access singleton_hello in a thread safe fashion. The class ThreadSpeakWithDtor uses the template class LockedSingletonWithDtor< singleton_hello> to access singleton_hello in a thread safe fashion. This class also destroys the instance of singleton_hello, in a thread safe fashion. #include #include #include "ThreadSafe.h" using namespace std; /// \class singleton_hello /// /// \brief This is a singleton class. It also has a destructor, "destroy_instance". /// /// Description: This is a singleton class. It also has a destructor, "destroy_instance". This class is very basic and provides /// minimal functionality. It is intended to illustrate the use of the two template classes LockedSingleton and LockedSingletonWithDtor. class singleton_hello { singleton_hello() { } static singleton_hello *instance; public: static singleton_hello* get_instance() { if (instance == 0) { instance = new singleton_hello(); } return instance; } static void destroy_instance() { if (instance != 0) { delete instance; instance = 0; } } string speak() { return "Hello World!"; } }; singleton_hello *singleton_hello::instance; boost::mutex LockedSingleton< singleton_hello>::Mutex; /// \class ThreadSpeak /// /// \brief This class uses the template class LockedSigleton to access the function singleton_hello::get_singleton, in a threadsafe function. /// /// This class uses the template class LockedSigleton to access the function singleton_hello::get_singleton, in a threadsafe function. It has operator ()() defined so that it can be used with the boost function create_thread. class ThreadSpeak { int id; public: ThreadSpeak(int id) : id(id) { } void operator()() { boost::shared_ptr< LockedSingleton< singleton_hello> > phello = LockedSingleton< singleton_hello >::get_instance(); cout << "Thread " << id << " says " << phello->get()->speak() << endl; } }; /// \class ThreadSpeakWithDetor /// /// \brief This class uses the template class LockedSigleton to access the function singleton_hello::get_singleton, in a threadsafe function. It also calls singleton_hello::destroy_instance in a thread safe manor. /// /// This class uses the template class LockedSigleton to access the function singleton_hello::get_singleton, in a threadsafe function. It also calls singleton_hello::destroy_instance in a thread safe manor. It has operator ()() defined so that it can be used with the boost function create_thread. class ThreadSpeakWithDetor { int id; public: ThreadSpeakWithDetor(int id) : id(id) { } void operator()() { { boost::shared_ptr< LockedSingletonWithDetor< singleton_hello> > phello = LockedSingletonWithDetor< singleton_hello >::get_instance(); cout << "Thread " << id << " says " << phello->get()->speak() << endl; } // note that phello must go out of scope, otherwise we get a deadlock when destroy_instance is called if (id % 2 == 0) { cout << "Thread " << id << " is now calling the detor for singleton_hello" << endl; LockedSingletonWithDetor< singleton_hello >::destroy_instance(); } } }; int main(int argc, char* argv[]) { cout << "creating threads with class LockedSingleton" << endl; boost::thread_group tgA; int i; for (i=0; i<5; i++) { tgA.create_thread( ThreadSpeak( i+1)); } tgA.join_all(); cout << "creating threads with class LockedSingletonWithDetor" << endl; boost::thread_group tgB; for (i=0; i<5; i++) { tgB.create_thread( ThreadSpeakWithDetor( i+1)); } tgB.join_all(); LockedSingletonWithDetor< singleton_hello >::destroy_instance(); return 0; }