1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_FRAME_SCOPED_INITIALIZATION_MANAGER_H_ 6 #define CHROME_FRAME_SCOPED_INITIALIZATION_MANAGER_H_ 7 8 #include "base/basictypes.h" 9 #include "base/lazy_instance.h" 10 #include "base/synchronization/lock.h" 11 12 namespace chrome_frame { 13 14 // A class intended to be instantiated on the stack in a dyanmically loaded 15 // shared object to initialize and shutdown the object's dependencies. |Traits| 16 // must be a type with two public static void(void) functions named Initialize 17 // and Shutdown. Traits::Initialize will be invoked when the first instance of 18 // this class is created and Traits::Shutdown will be invoked when the last one 19 // is destroyed. 20 template<class Traits> 21 class ScopedInitializationManager { 22 public: 23 ScopedInitializationManager() { AddRef(); } 24 ~ScopedInitializationManager() { Release(); } 25 26 private: 27 static void AddRef() { 28 base::AutoLock auto_lock(lock_.Get()); 29 DCHECK_LT(ref_count_, kuint32max); 30 if (++ref_count_ == 1) 31 Traits::Initialize(); 32 } 33 34 static void Release() { 35 base::AutoLock auto_lock(lock_.Get()); 36 DCHECK_GT(ref_count_, 0U); 37 if (--ref_count_ == 0) 38 Traits::Shutdown(); 39 } 40 41 static base::LazyInstance<base::Lock>::Leaky lock_; 42 static uint32 ref_count_; 43 DISALLOW_COPY_AND_ASSIGN(ScopedInitializationManager); 44 }; 45 46 template<class Traits> base::LazyInstance<base::Lock>::Leaky 47 ScopedInitializationManager<Traits>::lock_ = LAZY_INSTANCE_INITIALIZER; 48 49 template<class Traits> uint32 50 ScopedInitializationManager<Traits>::ref_count_ = 0; 51 52 } // namespace chrome_frame 53 54 #endif // CHROME_FRAME_SCOPED_INITIALIZATION_MANAGER_H_ 55