/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef WEBRTC_SYSTEM_WRAPPERS_INTERFACE_STATICINSTANCETEMPLATE_H_
#define WEBRTC_SYSTEM_WRAPPERS_INTERFACE_STATICINSTANCETEMPLATE_H_

#include <assert.h>

#include "critical_section_wrapper.h"
#ifdef _WIN32
#include "fix_interlocked_exchange_pointer_win.h"
#endif

namespace webrtc {

enum CountOperation {
  kRelease,
  kAddRef,
  kAddRefNoCreate
};
enum CreateOperation {
  kInstanceExists,
  kCreate,
  kDestroy
};

template <class T>
// Construct On First Use idiom. Avoids
// "static initialization order fiasco".
static T* GetStaticInstance(CountOperation count_operation) {
  // TODO (hellner): use atomic wrapper instead.
  static volatile long instance_count = 0;
  static T* volatile instance = NULL;
  CreateOperation state = kInstanceExists;
#ifndef _WIN32
  // This memory is staticly allocated once. The application does not try to
  // free this memory. This approach is taken to avoid issues with
  // destruction order for statically allocated memory. The memory will be
  // reclaimed by the OS and memory leak tools will not recognize memory
  // reachable from statics leaked so no noise is added by doing this.
  static CriticalSectionWrapper* crit_sect(
      CriticalSectionWrapper::CreateCriticalSection());
  CriticalSectionScoped lock(crit_sect);

  if (count_operation ==
      kAddRefNoCreate && instance_count == 0) {
    return NULL;
  }
  if (count_operation ==
      kAddRef ||
      count_operation == kAddRefNoCreate) {
    instance_count++;
    if (instance_count == 1) {
      state = kCreate;
    }
  } else {
    instance_count--;
    if (instance_count == 0) {
      state = kDestroy;
    }
  }
  if (state == kCreate) {
    instance = T::CreateInstance();
  } else if (state == kDestroy) {
    T* old_instance = instance;
    instance = NULL;
    // The state will not change past this point. Release the critical
    // section while deleting the object in case it would be blocking on
    // access back to this object. (This is the case for the tracing class
    // since the thread owned by the tracing class also traces).
    // TODO(hellner): this is a bit out of place but here goes, de-couple
    // thread implementation with trace implementation.
    crit_sect->Leave();
    if (old_instance) {
      delete old_instance;
    }
    // Re-acquire the lock since the scoped critical section will release
    // it.
    crit_sect->Enter();
    return NULL;
  }
#else  // _WIN32
  if (count_operation ==
      kAddRefNoCreate && instance_count == 0) {
    return NULL;
  }
  if (count_operation == kAddRefNoCreate) {
    if (1 == InterlockedIncrement(&instance_count)) {
      // The instance has been destroyed by some other thread. Rollback.
      InterlockedDecrement(&instance_count);
      assert(false);
      return NULL;
    }
    // Sanity to catch corrupt state.
    if (instance == NULL) {
      assert(false);
      InterlockedDecrement(&instance_count);
      return NULL;
    }
  } else if (count_operation == kAddRef) {
    if (instance_count == 0) {
      state = kCreate;
    } else {
      if (1 == InterlockedIncrement(&instance_count)) {
        // InterlockedDecrement because reference count should not be
        // updated just yet (that's done when the instance is created).
        InterlockedDecrement(&instance_count);
        state = kCreate;
      }
    }
  } else {
    int newValue = InterlockedDecrement(&instance_count);
    if (newValue == 0) {
      state = kDestroy;
    }
  }

  if (state == kCreate) {
    // Create instance and let whichever thread finishes first assign its
    // local copy to the global instance. All other threads reclaim their
    // local copy.
    T* new_instance = T::CreateInstance();
    if (1 == InterlockedIncrement(&instance_count)) {
      T* old_value = static_cast<T*> (InterlockedExchangePointer(
          reinterpret_cast<void* volatile*>(&instance), new_instance));
      assert(old_value == NULL);
      assert(instance);
    } else {
      InterlockedDecrement(&instance_count);
      if (new_instance) {
        delete static_cast<T*>(new_instance);
      }
    }
  } else if (state == kDestroy) {
    T* old_value = static_cast<T*> (InterlockedExchangePointer(
        reinterpret_cast<void* volatile*>(&instance), NULL));
    if (old_value) {
      delete static_cast<T*>(old_value);
    }
    return NULL;
  }
#endif  // #ifndef _WIN32
  return instance;
}

}  // namspace webrtc

#endif  // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_STATICINSTANCETEMPLATE_H_
