IPythonThreading.h#

Fully qualified name: carb/scripting/IPythonThreading.h

File members: carb/scripting/IPythonThreading.h

// Copyright (c) 2024, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto. Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
//

#pragma once

#include "../Interface.h"
#include "../InterfaceUtils.h"

namespace carb
{
namespace scripting
{

enum class PythonThreadingState
{
    eNotLoaded,
    eLoaded,
    eInitialized,
};

class IPythonThreading
{
public:
    CARB_PLUGIN_INTERFACE("carb::scripting::IPythonThreading", 1, 0);

    virtual PythonThreadingState checkLoaded() = 0;

    virtual bool ownsGil() const = 0;

private:
    // Use AcquirePythonGil instead
    friend class AcquirePythonGil;
    virtual void* acquireGil() = 0;
    virtual void releaseGil(void*) = 0;

    // Use ReleasePythonGil instead
    friend class ReleasePythonGil;
    virtual void* saveState() = 0;
    virtual void restoreState(void*) = 0;

public:
};

class [[nodiscard]] AcquirePythonGil
{
    IPythonThreading* m_threading;
    void* m_state;

public:
    AcquirePythonGil() : m_threading(carb::getCachedInterface<IPythonThreading>()), m_state(nullptr)
    {
        if (m_threading)
        {
            m_state = m_threading->acquireGil();
        }
    }
    ~AcquirePythonGil()
    {
        if (m_threading)
        {
            m_threading->releaseGil(m_state);
        }
    }
};

class [[nodiscard]] ReleasePythonGil
{
    IPythonThreading* m_threading;
    void* m_state;

public:
    ReleasePythonGil() : m_threading(carb::getCachedInterface<IPythonThreading>()), m_state(nullptr)
    {
        if (m_threading)
        {
            m_state = m_threading->saveState();
        }
    }
    ~ReleasePythonGil()
    {
        if (m_threading && m_state)
        {
            m_threading->restoreState(m_state);
        }
    }
};

} // namespace scripting
} // namespace carb