Vault
4.1
|
00001 /* 00002 Copyright c1997-2014 Trygve Isaacson. All rights reserved. 00003 This file is part of the Code Vault version 4.1 00004 http://www.bombaydigital.com/ 00005 License: MIT. See LICENSE.md in the Vault top level directory. 00006 */ 00007 00008 #include "vshutdownregistry.h" 00009 00010 #include "vmutex.h" 00011 #include "vmutexlocker.h" 00012 00013 VShutdownRegistry* VShutdownRegistry::gInstance = NULL; 00014 00015 // This style of static mutex declaration and access ensures correct 00016 // initialization if accessed during the static initialization phase. 00017 static VMutex* _mutexInstance() { 00018 static VMutex gMutex("VShutdownRegistry _mutexInstance() gMutex"); 00019 return &gMutex; 00020 } 00021 00022 // static 00023 VShutdownRegistry* VShutdownRegistry::instance() { 00024 VMutexLocker locker(_mutexInstance(), "VShutdownRegistry::instance()"); 00025 00026 if (gInstance == NULL) { 00027 gInstance = new VShutdownRegistry(); 00028 } 00029 00030 return gInstance; 00031 } 00032 00033 // static 00034 void VShutdownRegistry::shutdown() { 00035 VMutexLocker locker(_mutexInstance(), "VShutdownRegistry::shutdown()"); 00036 00037 if (gInstance != NULL) { 00038 delete gInstance; 00039 gInstance = NULL; 00040 } 00041 } 00042 00043 void VShutdownRegistry::registerHandler(IVShutdownHandler* handler) { 00044 VMutexLocker locker(_mutexInstance(), "VShutdownRegistry::registerHandler()"); 00045 00046 mHandlers.push_back(handler); 00047 } 00048 00049 void VShutdownRegistry::registerFunction(shutdownFunction func) { 00050 VMutexLocker locker(_mutexInstance(), "VShutdownRegistry::registerFunction()"); 00051 00052 mFunctions.push_back(func); 00053 } 00054 00055 VShutdownRegistry::~VShutdownRegistry() { 00056 // Note that this is only called via our static shutdown() function, 00057 // which takes responsibility for thread-safety. Don't lock, or we'll 00058 // have a deadlock. 00059 00060 for (ShutdownFunctionList::iterator i = mFunctions.begin(); i != mFunctions.end(); ++i) { 00061 shutdownFunction func = (*i); 00062 00063 func(); 00064 } 00065 00066 for (ShutdownHandlerList::iterator i = mHandlers.begin(); i != mHandlers.end(); ++i) { 00067 IVShutdownHandler* handler = (*i); 00068 00069 bool deleteHandler = handler->mDeleteAfterShutdown; // save first; _shutdown() could delete handler 00070 handler->_shutdown(); 00071 00072 if (deleteHandler) { 00073 delete handler; 00074 } 00075 00076 (*i) = NULL; 00077 } 00078 } 00079