Skip to content

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

@colesbury

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]*/
staticPyObject*
_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]*/staticPyObject*_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:

staticPyObject*_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(); returnreturn_value}

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

Linked PRs

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions