// Copyright 2008 Google Inc. All Rights Reserved.
//
// The first call to GoogleOnceInit() with a particular GoogleOnceType
// argument will run the specified function. Other calls with the same
// argument will not run the function, but will wait for the provided
// function to finish running (if it is still running). This provides
// a safe, simple, and fast mechanism for one-time initialization in a
// multi-threaded process.
//
// This module is a replacement for pthread_once().  It was added
// since some versions of pthread_once() call the supplied function
//
// Example usage:
//   static GoogleOnceType once = GOOGLE_ONCE_INIT;
//   static void Initializer() {
//     ... do initialization ...
//   }
//   ...
//   void SomeFunction() {
//     GoogleOnceInit(&once, &Initializer);
//     ...
//   }

#ifndef BASE_ONCE_H_
#define BASE_ONCE_H_

#include "kudu/gutil/atomicops.h"
#include "kudu/gutil/macros.h"
#include "kudu/gutil/port.h"
#include "kudu/gutil/type_traits.h"

// The following enum values are not for use by clients
enum {
  GOOGLE_ONCE_INTERNAL_INIT  = 0,
  GOOGLE_ONCE_INTERNAL_RUNNING = 0x65C2937B,  // an improbable 32-bit value
  GOOGLE_ONCE_INTERNAL_WAITER = 0x05A308D2,  // a different improbable value
  GOOGLE_ONCE_INTERNAL_DONE = 0x3F2D8AB0,  // yet another improbable value
};

struct GoogleOnceType {
  Atomic32 state;
};

#define GOOGLE_ONCE_INIT { GOOGLE_ONCE_INTERNAL_INIT }

// For internal use only.
extern void GoogleOnceInternalInit(Atomic32* state, void (*func)(),
                                   void (*func_with_arg)(void*), void* arg);

inline void GoogleOnceInit(GoogleOnceType* state, void (*func)()) {
  Atomic32 s = Acquire_Load(&state->state);
  if (PREDICT_FALSE(s != GOOGLE_ONCE_INTERNAL_DONE)) {
    GoogleOnceInternalInit(&state->state, func, 0, 0);
  }
}

// A version of GoogleOnceInit where the function argument takes a pointer
// of arbitrary type.
template<typename T>
inline void GoogleOnceInitArg(GoogleOnceType* state,
                              void (*func_with_arg)(T*), T* arg) {
  Atomic32 s = Acquire_Load(&state->state);
  if (PREDICT_FALSE(s != GOOGLE_ONCE_INTERNAL_DONE)) {
    // Deal with const T as well as non-const T.
    typedef typename base::remove_const<T>::type mutable_T;
    GoogleOnceInternalInit(&state->state, 0,
                           reinterpret_cast<void(*)(void*)>(func_with_arg),
                           const_cast<mutable_T*>(arg));
  }
}

// GoogleOnceDynamic is like GoogleOnceType, but is dynamically
// initialized instead of statically initialized.  This should be used only
// when the variable is not of static storage class.
// It might be used to delay expensive initialization of part of a
// dynamically-allocated data structure until it is known to be needed.  For
// example:
//   class MyType {
//     GoogleOnceDynamic once_;
//     ComplexStuff* complex_stuff_;
//     static void InitComplexStuff(MyType* me) {
//       me->complex_stuff_ = ...;
//     }
//    public:
//     ComplexStuff* complex_stuff() {
//       this->once_.Init(&InitComplexStuff, this);
//       return this->complex_stuff_;
//     }
//   }
class GoogleOnceDynamic {
 public:
  GoogleOnceDynamic() : state_(GOOGLE_ONCE_INTERNAL_INIT) { }

  // If this->Init() has not been called before by any thread,
  // execute (*func_with_arg)(arg) then return.
  // Otherwise, wait until that prior invocation has finished
  // executing its function, then return.
  template<typename T>
  void Init(void (*func_with_arg)(T*), T* arg) {
    Atomic32 s = Acquire_Load(&this->state_);
    if (PREDICT_FALSE(s != GOOGLE_ONCE_INTERNAL_DONE)) {
      // Deal with const T as well as non-const T.
      typedef typename base::remove_const<T>::type mutable_T;
      GoogleOnceInternalInit(&this->state_, 0,
                             reinterpret_cast<void (*)(void*)>(func_with_arg),
                             const_cast<mutable_T*>(arg));
    }
  }
 private:
  Atomic32 state_;
  DISALLOW_COPY_AND_ASSIGN(GoogleOnceDynamic);
};

#endif  // BASE_ONCE_H_
