Skip to content

Expose _PyCriticalSection_BeginMutex as a public API #133296

@hawkinsp

Description

@hawkinsp

Feature or enhancement

Proposal:

It would be helpful to expose _PyCriticalSection_BeginMutex as a public API.

There are times when one does not have really have a PyObject, but still might want to use a critical section. For example, we wanted to use a critical section to protect some initialization code in a C extension module, where we wanted to write something like this:

static PyMutex mu;
static PyObject* mymodule = nullptr;

// It is important that we use a critical section here rather than a regular
// PyMutex, say 'M', because we need to avoid the following deadlock:
// * thread T1 holds M and calls ImportModule, which attempts to acquire a
//   critical section C.
// * thread T2 holds critical section C and attempts to call this code and
//   acquire M.
// In general, if you're going to hold a lock while calling into Python code, it had better be a critical section.

PyCriticalSection cs;
_PyCriticalSection_BeginMutex(&cs, &mu);
if (!mymodule) {
    PyObject *m = PyImport_ImportModule("mymodule");

    // Importing may have released the critical section, so it is possible
    // another thread might have populated mymodule. Make sure we clean up after
    // ourselves in that case.
    std::swap(mymodule, m);
    Py_XDECREF(m);
}
PyCriticalSection_End(&cs);

Currently one would have to write something like the following instead:

static PyObject object_for_mu;  // Not really an object, we just want its mutex.
static PyObject* mymodule = nullptr;

PyCriticalSection cs;
PyCriticalSection_Begin(&cs, &object_for_mu);
if (!mymodule) {
    PyObject *m = PyImport_ImportModule("mymodule");

    std::swap(mymodule, m);
    Py_XDECREF(m);
}
PyCriticalSection_End(&cs);

@colesbury

Has this already been discussed elsewhere?

This is a minor feature, which does not need previous discussion elsewhere

Links to previous discussion of this feature:

No response

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      pFad - Phonifier reborn

      Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

      Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


      Alternative Proxies:

      Alternative Proxy

      pFad Proxy

      pFad v3 Proxy

      pFad v4 Proxy