// Copyright (c) 2011 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.

// The LazyInstance<Type, Traits> class manages a single instance of Type,
// which will be lazily created on the first time it's accessed.  This class is
// useful for places you would normally use a function-level static, but you
// need to have guaranteed thread-safety.  The Type constructor will only ever
// be called once, even if two threads are racing to create the object.  Get()
// and Pointer() will always return the same, completely initialized instance.
// When the instance is constructed it is registered with AtExitManager.  The
// destructor will be called on program exit.
//
// LazyInstance is completely thread safe, assuming that you create it safely.
// The class was designed to be POD initialized, so it shouldn't require a
// static constructor.  It really only makes sense to declare a LazyInstance as
// a global variable using the base::LinkerInitialized constructor.
//
// LazyInstance is similar to Singleton, except it does not have the singleton
// property.  You can have multiple LazyInstance's of the same type, and each
// will manage a unique instance.  It also preallocates the space for Type, as
// to avoid allocating the Type instance on the heap.  This may help with the
// performance of creating the instance, and reducing heap fragmentation.  This
// requires that Type be a complete type so we can determine the size.
//
// Example usage:
//   static LazyInstance<MyClass> my_instance(base::LINKER_INITIALIZED);
//   void SomeMethod() {
//     my_instance.Get().SomeMethod();  // MyClass::SomeMethod()
//
//     MyClass* ptr = my_instance.Pointer();
//     ptr->DoDoDo();  // MyClass::DoDoDo
//   }

#ifndef BASE_LAZY_INSTANCE_H_
#define BASE_LAZY_INSTANCE_H_
#pragma once

#include <new>  // For placement new.

#include "base/atomicops.h"
#include "base/base_api.h"
#include "base/basictypes.h"
#include "base/third_party/dynamic_annotations/dynamic_annotations.h"
#include "base/threading/thread_restrictions.h"

namespace base {

template <typename Type>
struct DefaultLazyInstanceTraits {
  static const bool kAllowedToAccessOnNonjoinableThread = false;

  static Type* New(void* instance) {
    // Use placement new to initialize our instance in our preallocated space.
    // The parenthesis is very important here to force POD type initialization.
    return new (instance) Type();
  }
  static void Delete(void* instance) {
    // Explicitly call the destructor.
    reinterpret_cast<Type*>(instance)->~Type();
  }
};

template <typename Type>
struct LeakyLazyInstanceTraits {
  static const bool kAllowedToAccessOnNonjoinableThread = true;

  static Type* New(void* instance) {
    return DefaultLazyInstanceTraits<Type>::New(instance);
  }
  // Rather than define an empty Delete function, we make Delete itself
  // a null pointer.  This allows us to completely sidestep registering
  // this object with an AtExitManager, which allows you to use
  // LeakyLazyInstanceTraits in contexts where you don't have an
  // AtExitManager.
  static void (*Delete)(void* instance);
};

template <typename Type>
void (*LeakyLazyInstanceTraits<Type>::Delete)(void* instance) = NULL;

// We pull out some of the functionality into a non-templated base, so that we
// can implement the more complicated pieces out of line in the .cc file.
class BASE_API LazyInstanceHelper {
 protected:
  enum {
    STATE_EMPTY    = 0,
    STATE_CREATING = 1,
    STATE_CREATED  = 2
  };

  explicit LazyInstanceHelper(LinkerInitialized /*unused*/) {/* state_ is 0 */}
  // Declaring a destructor (even if it's empty) will cause MSVC to register a
  // static initializer to register the empty destructor with atexit().

  // Check if instance needs to be created. If so return true otherwise
  // if another thread has beat us, wait for instance to be created and
  // return false.
  bool NeedsInstance();

  // After creating an instance, call this to register the dtor to be called
  // at program exit and to update the state to STATE_CREATED.
  void CompleteInstance(void* instance, void (*dtor)(void*));

  base::subtle::Atomic32 state_;

 private:
  DISALLOW_COPY_AND_ASSIGN(LazyInstanceHelper);
};

// Allow preservation of object alignment in the lazy instance when using GCC.
// __alignof__ is only defined for GCC > 4.2.
#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2))
#define LAZY_ALIGN(T) __attribute__((aligned(__alignof__(T))))
#else
#define LAZY_ALIGN(T)
#endif

template <typename Type, typename Traits = DefaultLazyInstanceTraits<Type> >
class LazyInstance : public LazyInstanceHelper {
 public:
  explicit LazyInstance(LinkerInitialized x) : LazyInstanceHelper(x) { }
  // Declaring a destructor (even if it's empty) will cause MSVC to register a
  // static initializer to register the empty destructor with atexit().

  Type& Get() {
    return *Pointer();
  }

  Type* Pointer() {
    if (!Traits::kAllowedToAccessOnNonjoinableThread)
      base::ThreadRestrictions::AssertSingletonAllowed();

    // We will hopefully have fast access when the instance is already created.
    if ((base::subtle::NoBarrier_Load(&state_) != STATE_CREATED) &&
        NeedsInstance()) {
      // Create the instance in the space provided by |buf_|.
      instance_ = Traits::New(buf_);
      // Traits::Delete will be null for LeakyLazyInstanceTraits
      void (*dtor)(void*) = Traits::Delete;
      CompleteInstance(this, (dtor == NULL) ? NULL : OnExit);
    }

    // This annotation helps race detectors recognize correct lock-less
    // synchronization between different threads calling Pointer().
    // We suggest dynamic race detection tool that "Traits::New" above
    // and CompleteInstance(...) happens before "return instance_" below.
    // See the corresponding HAPPENS_BEFORE in CompleteInstance(...).
    ANNOTATE_HAPPENS_AFTER(&state_);
    return instance_;
  }

  bool operator==(Type* p) {
    switch (base::subtle::NoBarrier_Load(&state_)) {
      case STATE_EMPTY:
        return p == NULL;
      case STATE_CREATING:
        return static_cast<int8*>(static_cast<void*>(p)) == buf_;
      case STATE_CREATED:
        return p == instance_;
      default:
        return false;
    }
  }

 private:
  // Adapter function for use with AtExit.  This should be called single
  // threaded, so don't use atomic operations.
  // Calling OnExit while the instance is in use by other threads is a mistake.
  static void OnExit(void* lazy_instance) {
    LazyInstance<Type, Traits>* me =
        reinterpret_cast<LazyInstance<Type, Traits>*>(lazy_instance);
    Traits::Delete(me->instance_);
    me->instance_ = NULL;
    base::subtle::Release_Store(&me->state_, STATE_EMPTY);
  }

  // Preallocate the space for the Type instance, and preserve alignment.
  int8 buf_[sizeof(Type)] LAZY_ALIGN(Type);
  Type *instance_;

  DISALLOW_COPY_AND_ASSIGN(LazyInstance);
};

#undef LAZY_ALIGN

}  // namespace base

#endif  // BASE_LAZY_INSTANCE_H_
