Skip to content

Commit a89ee4b

Browse files
gh-141004: Document missing PyThread* APIs (GH-141810)
Co-authored-by: Victor Stinner <vstinner@python.org>
1 parent 202fce0 commit a89ee4b

File tree

1 file changed

+217
-0
lines changed

1 file changed

+217
-0
lines changed

Doc/c-api/init.rst

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2539,3 +2539,220 @@ code triggered by the finalizer blocks and calls :c:func:`PyEval_SaveThread`.
25392539
In the default build, this macro expands to ``}``.
25402540
25412541
.. versionadded:: 3.13
2542+
2543+
2544+
Legacy Locking APIs
2545+
-------------------
2546+
2547+
These APIs are obsolete since Python 3.13 with the introduction of
2548+
:c:type:`PyMutex`.
2549+
2550+
.. versionchanged:: 3.15
2551+
These APIs are now a simple wrapper around ``PyMutex``.
2552+
2553+
2554+
.. c:type:: PyThread_type_lock
2555+
2556+
A pointer to a mutual exclusion lock.
2557+
2558+
2559+
.. c:type:: PyLockStatus
2560+
2561+
The result of acquiring a lock with a timeout.
2562+
2563+
.. c:namespace:: NULL
2564+
2565+
.. c:enumerator:: PY_LOCK_FAILURE
2566+
2567+
Failed to acquire the lock.
2568+
2569+
.. c:enumerator:: PY_LOCK_ACQUIRED
2570+
2571+
The lock was successfully acquired.
2572+
2573+
.. c:enumerator:: PY_LOCK_INTR
2574+
2575+
The lock was interrupted by a signal.
2576+
2577+
2578+
.. c:function:: PyThread_type_lock PyThread_allocate_lock(void)
2579+
2580+
Allocate a new lock.
2581+
2582+
On success, this function returns a lock; on failure, this
2583+
function returns ``0`` without an exception set.
2584+
2585+
The caller does not need to hold an :term:`attached thread state`.
2586+
2587+
.. versionchanged:: 3.15
2588+
This function now always uses :c:type:`PyMutex`. In prior versions, this
2589+
would use a lock provided by the operating system.
2590+
2591+
2592+
.. c:function:: void PyThread_free_lock(PyThread_type_lock lock)
2593+
2594+
Destroy *lock*. The lock should not be held by any thread when calling
2595+
this.
2596+
2597+
The caller does not need to hold an :term:`attached thread state`.
2598+
2599+
2600+
.. c:function:: PyLockStatus PyThread_acquire_lock_timed(PyThread_type_lock lock, long long microseconds, int intr_flag)
2601+
2602+
Acquire *lock* with a timeout.
2603+
2604+
This will wait for *microseconds* microseconds to acquire the lock. If the
2605+
timeout expires, this function returns :c:enumerator:`PY_LOCK_FAILURE`.
2606+
If *microseconds* is ``-1``, this will wait indefinitely until the lock has
2607+
been released.
2608+
2609+
If *intr_flag* is ``1``, acquiring the lock may be interrupted by a signal,
2610+
in which case this function returns :c:enumerator:`PY_LOCK_INTR`. Upon
2611+
interruption, it's generally expected that the caller makes a call to
2612+
:c:func:`Py_MakePendingCalls` to propagate an exception to Python code.
2613+
2614+
If the lock is successfully acquired, this function returns
2615+
:c:enumerator:`PY_LOCK_ACQUIRED`.
2616+
2617+
The caller does not need to hold an :term:`attached thread state`.
2618+
2619+
2620+
.. c:function:: int PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
2621+
2622+
Acquire *lock*.
2623+
2624+
If *waitflag* is ``1`` and another thread currently holds the lock, this
2625+
function will wait until the lock can be acquired and will always return
2626+
``1``.
2627+
2628+
If *waitflag* is ``0`` and another thread holds the lock, this function will
2629+
not wait and instead return ``0``. If the lock is not held by any other
2630+
thread, then this function will acquire it and return ``1``.
2631+
2632+
Unlike :c:func:`PyThread_acquire_lock_timed`, acquiring the lock cannot be
2633+
interrupted by a signal.
2634+
2635+
The caller does not need to hold an :term:`attached thread state`.
2636+
2637+
2638+
.. c:function:: int PyThread_release_lock(PyThread_type_lock lock)
2639+
2640+
Release *lock*. If *lock* is not held, then this function issues a
2641+
fatal error.
2642+
2643+
The caller does not need to hold an :term:`attached thread state`.
2644+
2645+
2646+
Operating System Thread APIs
2647+
============================
2648+
2649+
.. c:macro:: PYTHREAD_INVALID_THREAD_ID
2650+
2651+
Sentinel value for an invalid thread ID.
2652+
2653+
This is currently equivalent to ``(unsigned long)-1``.
2654+
2655+
2656+
.. c:function:: unsigned long PyThread_start_new_thread(void (*func)(void *), void *arg)
2657+
2658+
Start function *func* in a new thread with argument *arg*.
2659+
The resulting thread is not intended to be joined.
2660+
2661+
*func* must not be ``NULL``, but *arg* may be ``NULL``.
2662+
2663+
On success, this function returns the identifier of the new thread; on failure,
2664+
this returns :c:macro:`PYTHREAD_INVALID_THREAD_ID`.
2665+
2666+
The caller does not need to hold an :term:`attached thread state`.
2667+
2668+
2669+
.. c:function:: unsigned long PyThread_get_thread_ident(void)
2670+
2671+
Return the identifier of the current thread, which will never be zero.
2672+
2673+
This function cannot fail, and the caller does not need to hold an
2674+
:term:`attached thread state`.
2675+
2676+
.. seealso::
2677+
:py:func:`threading.get_ident`
2678+
2679+
2680+
.. c:function:: PyObject *PyThread_GetInfo(void)
2681+
2682+
Get general information about the current thread in the form of a
2683+
:ref:`struct sequence <struct-sequence-objects>` object. This information is
2684+
accessible as :py:attr:`sys.thread_info` in Python.
2685+
2686+
On success, this returns a new :term:`strong reference` to the thread
2687+
information; on failure, this returns ``NULL`` with an exception set.
2688+
2689+
The caller must hold an :term:`attached thread state`.
2690+
2691+
2692+
.. c:macro:: PY_HAVE_THREAD_NATIVE_ID
2693+
2694+
This macro is defined when the system supports native thread IDs.
2695+
2696+
2697+
.. c:function:: unsigned long PyThread_get_thread_native_id(void)
2698+
2699+
Get the native identifier of the current thread as it was assigned by the operating
2700+
system's kernel, which will never be less than zero.
2701+
2702+
This function is only available when :c:macro:`PY_HAVE_THREAD_NATIVE_ID` is
2703+
defined.
2704+
2705+
This function cannot fail, and the caller does not need to hold an
2706+
:term:`attached thread state`.
2707+
2708+
.. seealso::
2709+
:py:func:`threading.get_native_id`
2710+
2711+
2712+
.. c:function:: void PyThread_exit_thread(void)
2713+
2714+
Terminate the current thread. This function is generally considered unsafe
2715+
and should be avoided. It is kept solely for backwards compatibility.
2716+
2717+
This function is only safe to call if all functions in the full call
2718+
stack are written to safely allow it.
2719+
2720+
.. warning::
2721+
2722+
If the current system uses POSIX threads (also known as "pthreads"),
2723+
this calls :manpage:`pthread_exit(3)`, which attempts to unwind the stack
2724+
and call C++ destructors on some libc implementations. However, if a
2725+
``noexcept`` function is reached, it may terminate the process.
2726+
Other systems, such as macOS, do unwinding.
2727+
2728+
On Windows, this function calls ``_endthreadex()``, which kills the thread
2729+
without calling C++ destructors.
2730+
2731+
In any case, there is a risk of corruption on the thread's stack.
2732+
2733+
.. deprecated:: 3.14
2734+
2735+
2736+
.. c:function:: void PyThread_init_thread(void)
2737+
2738+
Initialize ``PyThread*`` APIs. Python executes this function automatically,
2739+
so there's little need to call it from an extension module.
2740+
2741+
2742+
.. c:function:: int PyThread_set_stacksize(size_t size)
2743+
2744+
Set the stack size of the current thread to *size* bytes.
2745+
2746+
This function returns ``0`` on success, ``-1`` if *size* is invalid, or
2747+
``-2`` if the system does not support changing the stack size. This function
2748+
does not set exceptions.
2749+
2750+
The caller does not need to hold an :term:`attached thread state`.
2751+
2752+
2753+
.. c:function:: size_t PyThread_get_stacksize(void)
2754+
2755+
Return the stack size of the current thread in bytes, or ``0`` if the system's
2756+
default stack size is in use.
2757+
2758+
The caller does not need to hold an :term:`attached thread state`.

0 commit comments

Comments
 (0)