IPythonThreading.h#

Fully qualified name: carb/scripting/IPythonThreading.h

File members: carb/scripting/IPythonThreading.h

// SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: LicenseRef-NvidiaProprietary
//
// NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
// property and proprietary rights in and to this material, related
// documentation and any modifications thereto. Any use, reproduction,
// disclosure or distribution of this material and related documentation
// without an express license agreement from NVIDIA CORPORATION or
// its affiliates 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