// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef COBALT_RENDERER_RASTERIZER_SKIA_SKIA_SRC_PORTS_SKMUTEX_STARBOARD_H_
#define COBALT_RENDERER_RASTERIZER_SKIA_SKIA_SRC_PORTS_SKMUTEX_STARBOARD_H_

#include "starboard/mutex.h"
#include "starboard/thread.h"

// A Starboard-based implementation of mutex, with support for static
// initialization without initializer/finalizer, which can cause race
// conditions at application exit.

// A SkBaseMutex is a POD structure that can be directly initialized
// at declaration time with SK_DECLARE_STATIC/GLOBAL_MUTEX. This avoids the
// generation of a static initializer/finalizer.
struct SkBaseMutex {
  void acquire() {
    SbMutexAcquire(&mutex_);
    SetAcquired();
  }

  void release() {
    SetReleased();
    SbMutexRelease(&mutex_);
  }

  void assertHeld() { AssertAcquired(); }

  SbMutex mutex_;

#ifdef SK_DEBUG
  void Init() {
    holding_thread_ = kSbThreadInvalid;
    initialized_ = true;
  }

  void SetAcquired() {
    if (!initialized_) {
      Init();
    }
    SB_DCHECK(holding_thread_ == kSbThreadInvalid);
    holding_thread_ = SbThreadGetCurrent();
  }

  void SetReleased() {
    SB_DCHECK(holding_thread_ == SbThreadGetCurrent());
    holding_thread_ = kSbThreadInvalid;
  }

  void AssertAcquired() const {
    SkASSERT(initialized_ && holding_thread_ != kSbThreadInvalid);
  }

  // |initialized_| will be default-initialized to |false| by the POD-style
  // initializer.
  bool initialized_;
  SbThread holding_thread_;
#else
  void Init() {}
  void SetAcquired() {}
  void SetReleased() {}
  void AssertAcquired() const {}
#endif  // SK_DEBUG
};

// A mutex that requires to be initialized through normal C++ construction,
// i.e. when it's a member of another class, or allocated on the heap.
class SkMutex : public SkBaseMutex {
 public:
  SkMutex() {
    Init();
    SbMutexCreate(&mutex_);
  }
  ~SkMutex() { SbMutexDestroy(&mutex_); }
};

#define SK_BASE_MUTEX_INIT \
  { SB_MUTEX_INITIALIZER }

// Using POD-style initialization prevents the generation of a static
// initializer.
//
// Without magic statics there are no thread safety guarantees on initialization
// of local statics (even POD). As a result, it is illegal to use
// SK_DECLARE_STATIC_MUTEX in a function.
//
// Because SkBaseMutex is not a primitive, a static SkBaseMutex cannot be
// initialized in a class with this macro.
#define SK_DECLARE_STATIC_MUTEX(name) \
  namespace {}                        \
  static SkBaseMutex name = SK_BASE_MUTEX_INIT

#endif  // COBALT_RENDERER_RASTERIZER_SKIA_SKIA_SRC_PORTS_SKMUTEX_STARBOARD_H_
