#ifndef TILE_BASE_THREAD_MUTEX_H
#define TILE_BASE_THREAD_MUTEX_H

#pragma once
#include "tile/base/thread/cond_var.h"

#include <memory>

namespace tile {

class Mutex final {
public:
    Mutex();
    ~Mutex();

    Mutex(const Mutex &)            = delete;
    Mutex &operator=(const Mutex &) = delete;

    void Lock();
    bool TryLock();
    void Unlock();

private:
    // for CondVar
    void *GetNativeHandle();

private:
    friend class ::tile::detail::cond_var::CondVarProxy;
    class Impl;
    std::unique_ptr<Impl> impl_;
};

class RecursiveMutex final {
public:
    RecursiveMutex();
    ~RecursiveMutex();

    RecursiveMutex(const RecursiveMutex &)            = delete;
    RecursiveMutex &operator=(const RecursiveMutex &) = delete;

    void Lock();
    bool TryLock();
    void Unlock();

private:
    class Impl;
    std::unique_ptr<Impl> impl_;
};

}// namespace tile

#endif// TILE_BASE_THREAD_MUTEX_H
