$extrastylesheet
libmesh_singleton.C
Go to the documentation of this file.
00001 // The libMesh Finite Element Library.
00002 // Copyright (C) 2002-2013 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
00003 
00004 // This library is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public
00006 // License as published by the Free Software Foundation; either
00007 // version 2.1 of the License, or (at your option) any later version.
00008 
00009 // This library is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // Lesser General Public License for more details.
00013 
00014 // You should have received a copy of the GNU Lesser General Public
00015 // License along with this library; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 
00018 
00019 
00020 // Local includes
00021 #include "libmesh/libmesh_singleton.h"
00022 #include "libmesh/threads.h"
00023 
00024 // C/C++ includes
00025 #include <vector>
00026 
00027 
00028 // --------------------------------------------------------
00029 // Local anonymous namespace to hold miscelaneous bits
00030 namespace
00031 {
00032 using namespace libMesh;
00033 
00034 // Mutex object for required locking
00035 typedef Threads::spin_mutex SingletonMutex;
00036 SingletonMutex singleton_mtx, setup_mtx;
00037 
00038 // global list of runtime Singleton objects - created dynamically,
00039 // cleaned up in reverse order.
00040 typedef std::vector<Singleton*> SingletonList;
00041 
00042 SingletonList& get_singleton_cache()
00043 {
00044   static SingletonList singleton_cache;
00045   return singleton_cache;
00046 }
00047 
00048 typedef std::vector<Singleton::Setup*> SetupList;
00049 SetupList& get_setup_cache()
00050 {
00051   static SetupList setup_cache;
00052   return setup_cache;
00053 }
00054 
00055 } // end anonymous namespace
00056 
00057 
00058 
00059 // --------------------------------------------------------
00060 // Local anonymous namespace to hold miscelaneous bits
00061 namespace libMesh
00062 {
00063 
00064 Singleton::Singleton ()
00065 {
00066   SingletonMutex::scoped_lock lock(singleton_mtx);
00067 
00068   get_singleton_cache().push_back (this);
00069 }
00070 
00071 
00072 
00073 Singleton::Setup::Setup ()
00074 {
00075   get_setup_cache().push_back (this);
00076 }
00077 
00078 
00079 
00080 void Singleton::setup ()
00081 {
00082   SingletonMutex::scoped_lock lock(setup_mtx);
00083 
00084   SetupList& setup_cache = get_setup_cache();
00085 
00086   for (SetupList::iterator it = setup_cache.begin();
00087        it!=setup_cache.end(); ++it)
00088     {
00089       libmesh_assert (*it != NULL);
00090       (*it)->setup();
00091     }
00092 }
00093 
00094 
00095 
00096 void Singleton::cleanup ()
00097 {
00098   SingletonMutex::scoped_lock lock(singleton_mtx);
00099 
00100   SingletonList& singleton_cache = get_singleton_cache();
00101 
00102   for (SingletonList::reverse_iterator it = singleton_cache.rbegin();
00103        it!=singleton_cache.rend(); ++it)
00104     {
00105       libmesh_assert (*it != NULL);
00106       delete *it;
00107       *it = NULL;
00108     }
00109 
00110   singleton_cache.clear();
00111 }
00112 
00113 
00114 
00115 } // namespace libMesh