// Copyright 2016 The Android Open Source Project
//
// 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.

#pragma once

#include "base/Compiler.h"

namespace android {

// In QEMU2, each virtual CPU runs on its own host threads, but all these
// threads are synchronized through a global mutex, which allows the virtual
// device code to not care about them.
//
// However, if you have to call, from any other thread, a low-level QEMU
// function that operate on virtual devices (e.g. some Android pipe-related
// functions), you must acquire the global mutex before doing so, and release
// it after that.

// This header provides a convenience interface class you can use to do
// just that, i.e.:
//
// 1) To operate on the lock, call VmLock::get() to retrieve the
//    current VmLock instance, then invoke its lock() and unlock()
//    methods.
//
// 2) Glue code should call VmLock::set() to inject their own implementation
//    into the process. The default implementation doesn't do anything.
//

class VmLock {
    DISALLOW_COPY_ASSIGN_AND_MOVE(VmLock);
public:
    VmLock() = default;
    virtual ~VmLock();

    // Lock the VM global mutex.
    virtual void lock() {}

    // Unlock the VM global mutex.
    virtual void unlock() {}

    // Returns true iff the lock is held by the current thread, false
    // otherwise. Note that for a correct implementation, that doesn't
    // only depend on the number of times that VmLock::lock() and
    // VmLock::unlock() were called, but also on other QEMU threads that
    // act on the global lock.
    virtual bool isLockedBySelf() const { return true; }

    // Return current VmLock instance. Cannot return nullptr.
    // NOT thread-safe, but we don't expect multiple threads to call this
    // concurrently at init time, and the worst that can happen is to leak
    // a single instance.
    static VmLock* get();

    // Returns whether or not there is a VmLock.
    // Does not instantiate a VmLock.
    static bool hasInstance();

    // Set new VmLock instance. Return old value, which cannot be nullptr and
    // can be deleted by the caller. If |vmLock| is nullptr, a new default
    // instance is created. NOTE: not thread-safe with regards to get().
    static VmLock* set(VmLock* vmLock);
};

// Convenience class to perform scoped VM locking.
class ScopedVmLock {
    DISALLOW_COPY_ASSIGN_AND_MOVE(ScopedVmLock);
public:
    ScopedVmLock(VmLock* vmLock = VmLock::get()) : mVmLock(vmLock) {
        mVmLock->lock();
    }

    ~ScopedVmLock() {
        mVmLock->unlock();
    }

private:
    VmLock* const mVmLock;
};

// Convenience class to perform scoped VM locking (but does not try
// to lock twice).
class RecursiveScopedVmLock {
    DISALLOW_COPY_ASSIGN_AND_MOVE(RecursiveScopedVmLock);
public:
    RecursiveScopedVmLock(VmLock* vmLock = VmLock::get()) {
        if (vmLock->isLockedBySelf()) {
            mVmLock = nullptr;
        } else {
            mVmLock = vmLock;
            vmLock->lock();
        }
    }

    ~RecursiveScopedVmLock() {
        if (mVmLock) {
            mVmLock->unlock();
        }
    }

private:
    VmLock* mVmLock;
};

// Convenience class to perform scoped VM locking (but does not try
// to lock twice), but no-ops if there is no instance.
class RecursiveScopedVmLockIfInstance {
    DISALLOW_COPY_ASSIGN_AND_MOVE(RecursiveScopedVmLockIfInstance);
public:
    RecursiveScopedVmLockIfInstance() {
        if (!VmLock::hasInstance()) return;

        VmLock* vmLock = VmLock::get();

        if (vmLock->isLockedBySelf()) {
            mVmLock = nullptr;
        } else {
            mVmLock = vmLock;
            vmLock->lock();
        }
    }

    ~RecursiveScopedVmLockIfInstance() {
        if (mVmLock) {
            mVmLock->unlock();
        }
    }

private:
    VmLock* mVmLock = nullptr;;
};

// Another convenience class for a code that may run either under a lock or not
// but needs to ensure that some part of it runs without a VmLock.
class ScopedVmUnlock {
    DISALLOW_COPY_ASSIGN_AND_MOVE(ScopedVmUnlock);
public:
    ScopedVmUnlock(VmLock* vmLock = VmLock::get()) {
        if (vmLock->isLockedBySelf()) {
            mVmLock = vmLock;
            vmLock->unlock();
        } else {
            mVmLock = nullptr;
        }
    }

    ~ScopedVmUnlock() {
        if (mVmLock) {
            mVmLock->lock();
        }
    }

private:
    VmLock* mVmLock;
};

}  // namespace android
