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