Skip to content

Commit f640f05

Browse files
committed
Improvements based on review feedback.
1 parent df33bbc commit f640f05

File tree

1 file changed

+32
-3
lines changed

1 file changed

+32
-3
lines changed

Doc/howto/free-threading-extensions.rst

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -275,8 +275,28 @@ The primary APIs for using critical sections are:
275275
* :c:macro:`Py_BEGIN_CRITICAL_SECTION2` and :c:macro:`Py_END_CRITICAL_SECTION2`
276276
- For locking two objects simultaneously
277277

278-
These macros are no-ops in non-free-threaded builds, so they can be safely
279-
added to code that needs to support both build types.
278+
These macros must be used in matching pairs and must appear in the same C
279+
scope, since they establish a new local scope. These macros are no-ops in
280+
non-free-threaded builds, so they can be safely added to code that needs to
281+
support both build types.
282+
283+
A common use of a critical section would be to lock an object while accessing
284+
an internal attribute of it. For example, if an extension type has an internal
285+
count field, you could use a critical section while reading or writing that
286+
field::
287+
288+
// read the count, returns new reference to internal count value
289+
PyObject *result;
290+
Py_BEGIN_CRITICAL_SECTION(obj);
291+
result = Py_NewRef(obj->count);
292+
Py_END_CRITICAL_SECTION();
293+
return result;
294+
295+
// write the count, consumes reference from new_count
296+
Py_BEGIN_CRITICAL_SECTION(obj);
297+
obj->count = new_count;
298+
Py_END_CRITICAL_SECTION();
299+
280300

281301
How Critical Sections Work
282302
..........................
@@ -292,7 +312,8 @@ blocking call. The key differences are:
292312

293313
* Critical sections operate on a per-object basis rather than globally
294314

295-
* Critical sections follow a stack discipline within each thread
315+
* Critical sections follow a stack discipline within each thread (the "begin" and
316+
"end" macros enforce this since they must be paired and within the same scope)
296317

297318
* Critical sections automatically release and reacquire locks around potential
298319
blocking operations
@@ -313,6 +334,14 @@ This means you cannot rely on nested critical sections to lock multiple objects
313334
at once, as the inner critical section may suspend the outer ones. Instead, use
314335
:c:macro:`Py_BEGIN_CRITICAL_SECTION2` to lock two objects simultaneously.
315336

337+
Note that the locks described above are only `PyMutex` based locks. The
338+
critical section implementation does not know about or affect other locking
339+
mechanisms that might be in use, like POSIX mutexes. Also note that while
340+
blocking on any `PyMutex` causes the critical sections to be suspended, only
341+
the mutexes that are part of the critical sections are released. If `PyMutex`
342+
is used without a critical section, it will not be released and therefore does
343+
not get the same deadlock avoidance.
344+
316345
Important Considerations
317346
........................
318347

0 commit comments

Comments
 (0)