// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_FRAME_SCOPED_INITIALIZATION_MANAGER_H_
#define CHROME_FRAME_SCOPED_INITIALIZATION_MANAGER_H_
#include "base/basictypes.h"
#include "base/lazy_instance.h"
#include "base/synchronization/lock.h"
namespace chrome_frame {
// A class intended to be instantiated on the stack in a dyanmically loaded
// shared object to initialize and shutdown the object's dependencies. |Traits|
// must be a type with two public static void(void) functions named Initialize
// and Shutdown. Traits::Initialize will be invoked when the first instance of
// this class is created and Traits::Shutdown will be invoked when the last one
// is destroyed.
template<class Traits>
class ScopedInitializationManager {
public:
ScopedInitializationManager() { AddRef(); }
~ScopedInitializationManager() { Release(); }
private:
static void AddRef() {
base::AutoLock auto_lock(lock_.Get());
DCHECK_LT(ref_count_, kuint32max);
if (++ref_count_ == 1)
Traits::Initialize();
}
static void Release() {
base::AutoLock auto_lock(lock_.Get());
DCHECK_GT(ref_count_, 0U);
if (--ref_count_ == 0)
Traits::Shutdown();
}
static base::LazyInstance<base::Lock>::Leaky lock_;
static uint32 ref_count_;
DISALLOW_COPY_AND_ASSIGN(ScopedInitializationManager);
};
template<class Traits> base::LazyInstance<base::Lock>::Leaky
ScopedInitializationManager<Traits>::lock_ = LAZY_INSTANCE_INITIALIZER;
template<class Traits> uint32
ScopedInitializationManager<Traits>::ref_count_ = 0;
} // namespace chrome_frame
#endif // CHROME_FRAME_SCOPED_INITIALIZATION_MANAGER_H_