Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:CARLA simulator Carla PythonUtil

From Leeroopedia
Knowledge Sources
Domains PythonBinding, Concurrency
Last Updated 2026-02-15 05:00 GMT

Overview

PythonUtil provides utilities for managing Python's Global Interpreter Lock (GIL) from C++ code, including RAII wrappers for acquiring and releasing the GIL and custom deleters for GIL-aware smart pointer cleanup.

Description

The PythonUtil class in the carla namespace provides essential GIL management tools for the C++/Python interface layer. All functionality is conditionally compiled based on the LIBCARLA_WITH_PYTHON_SUPPORT preprocessor macro.

Static method:

  • ThisThreadHasTheGIL(): Returns true if the current thread holds the GIL. On Python 3, uses PyGILState_Check(). On Python 2, checks if the current thread state matches PyGILState_GetThisThreadState(). When Python support is disabled, always returns false.

RAII GIL wrappers (active when Python support is enabled):

  • AcquireGIL: Acquires the GIL in the constructor via PyGILState_Ensure() and releases it in the destructor via PyGILState_Release(). Inherits from NonCopyable. Use this when calling Python code from a C++ thread that does not hold the GIL.
  • ReleaseGIL: Releases the GIL in the constructor via PyEval_SaveThread() and re-acquires it in the destructor via PyEval_RestoreThread(). Inherits from NonCopyable. Use this when performing blocking I/O operations from a Python thread to allow other Python threads to run.

When Python support is disabled, both AcquireGIL and ReleaseGIL are empty classes that inherit from NonCopyable (no-op).

Custom deleters for smart pointers:

  • AcquireGILDeleter: A functor that acquires the GIL before deleting the pointed-to object, if the current thread does not already hold the GIL. Use this with shared_ptr or unique_ptr when the destructor of the managed object may interact with Python objects.
  • ReleaseGILDeleter: A functor that releases the GIL before deleting the pointed-to object, if the current thread holds the GIL. Use this when destruction involves blocking operations that should not hold the GIL.

Usage

These utilities are used throughout the CARLA Python client bindings to ensure correct GIL management when C++ callbacks execute on background threads or when blocking operations need to release the GIL to avoid deadlocks.

Code Reference

Source Location

  • Repository: CARLA
  • File: LibCarla/source/carla/PythonUtil.h

Signature

class PythonUtil {
public:
    static bool ThisThreadHasTheGIL();

    class AcquireGIL : private NonCopyable {
    public:
        AcquireGIL();
        ~AcquireGIL();
    };

    class ReleaseGIL : private NonCopyable {
    public:
        ReleaseGIL();
        ~ReleaseGIL();
    };

    class AcquireGILDeleter {
    public:
        template <typename T>
        void operator()(T *ptr) const;
    };

    class ReleaseGILDeleter {
    public:
        template <typename T>
        void operator()(T *ptr) const;
    };
};

Import

#include "carla/PythonUtil.h"

I/O Contract

Inputs

Name Type Required Description
(none for AcquireGIL/ReleaseGIL) N/A N/A RAII objects, no inputs required
ptr T* Yes (Deleters) Pointer to the object to delete with GIL management

Outputs

Name Type Description
ThisThreadHasTheGIL() bool Whether the current thread holds the Python GIL

Usage Examples

// Acquire the GIL to call Python from a C++ thread
{
    carla::PythonUtil::AcquireGIL lock;
    // Safe to call Python C API here
    PyObject *result = PyObject_CallFunction(callback, "i", 42);
}  // GIL released automatically

// Release the GIL for blocking I/O from a Python thread
{
    carla::PythonUtil::ReleaseGIL unlock;
    // Blocking network call that doesn't need the GIL
    auto data = socket.read();
}  // GIL re-acquired automatically

// Use AcquireGILDeleter with shared_ptr
auto ptr = std::shared_ptr<PyObject>(
    pyObj, carla::PythonUtil::AcquireGILDeleter{});
// When ptr is destroyed from a non-Python thread, the GIL is acquired first

// Check GIL state
if (carla::PythonUtil::ThisThreadHasTheGIL()) {
    // Already have the GIL, safe to call Python directly
}

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment