Skip to content

Argument Clinic: Add support for PEP 703's critical sections (Py_BEGIN_CRITICAL_SECTION()) #111903

Description

@colesbury

Feature or enhancement

PEP 703 in large part relies on replacing the GIL with fine grained per-object locks. The primary way to acquire and release these locks is through the critical section API (#111569). It would be helpful if argument clinic could auto generate the API calls in the binding code when specified.

For example, the bufferedio.c will require per-object locking around most calls for thread-safety in --disable-gil builds.

As an example, the _io._Buffered.close function is written as:

/*[clinic input]
_io._Buffered.close
[clinic start generated code]*/
static PyObject *
_io__Buffered_close_impl(buffered *self)
/*[clinic end generated code: output=7280b7b42033be0c input=d20b83d1ddd7d805]*/

We might add a @critical_section directive to designate that argument clinic should generate Py_BEGIN_CRITICAL_SECTION() and Py_END_CRITICAL_SECTION() in the binding code before calling _io__Buffered_close_impl.

/*[clinic input]
@critical_section
_io._Buffered.close
[clinic start generated code]*/

static PyObject *
_io__Buffered_close_impl(buffered *self)
/*[clinic end generated code: output=7280b7b42033be0c input=d20b83d1ddd7d805]*/

The generated binding code in bufferedio.c.h would then look like:

static PyObject *
_io__Buffered_close(buffered *self, PyObject *Py_UNUSED(ignored))
{
    PyObject *return_value = NULL;

    Py_BEGIN_CRITICAL_SECTION(self);
    return_value = _io__Buffered_close_impl(self);
    Py_END_CRITICAL_SECTION();

    return return_value;
}

Note that Py_BEGIN/END_CRITICAL_SECTION() are no-ops in the default build.

Linked PRs

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions