1 #ifndef Py_PYTHREAD_H
2 #define Py_PYTHREAD_H
3 
4 typedef void *PyThread_type_lock;
5 
6 #ifdef __cplusplus
7 extern "C" {
8 #endif
9 
10 /* Return status codes for Python lock acquisition.  Chosen for maximum
11  * backwards compatibility, ie failure -> 0, success -> 1.  */
12 typedef enum PyLockStatus {
13     PY_LOCK_FAILURE = 0,
14     PY_LOCK_ACQUIRED = 1,
15     PY_LOCK_INTR
16 } PyLockStatus;
17 
18 PyAPI_FUNC(void) PyThread_init_thread(void);
19 PyAPI_FUNC(unsigned long) PyThread_start_new_thread(void (*)(void *), void *);
20 PyAPI_FUNC(void) _Py_NO_RETURN PyThread_exit_thread(void);
21 PyAPI_FUNC(unsigned long) PyThread_get_thread_ident(void);
22 
23 #if defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(_WIN32) || defined(_AIX)
24 #define PY_HAVE_THREAD_NATIVE_ID
25 PyAPI_FUNC(unsigned long) PyThread_get_thread_native_id(void);
26 #endif
27 
28 PyAPI_FUNC(PyThread_type_lock) PyThread_allocate_lock(void);
29 PyAPI_FUNC(void) PyThread_free_lock(PyThread_type_lock);
30 PyAPI_FUNC(int) PyThread_acquire_lock(PyThread_type_lock, int);
31 #define WAIT_LOCK       1
32 #define NOWAIT_LOCK     0
33 
34 /* PY_TIMEOUT_T is the integral type used to specify timeouts when waiting
35    on a lock (see PyThread_acquire_lock_timed() below).
36    PY_TIMEOUT_MAX is the highest usable value (in microseconds) of that
37    type, and depends on the system threading API.
38 
39    NOTE: this isn't the same value as `_thread.TIMEOUT_MAX`.  The _thread
40    module exposes a higher-level API, with timeouts expressed in seconds
41    and floating-point numbers allowed.
42 */
43 #define PY_TIMEOUT_T long long
44 
45 #if defined(_POSIX_THREADS)
46    /* PyThread_acquire_lock_timed() uses _PyTime_FromNanoseconds(us * 1000),
47       convert microseconds to nanoseconds. */
48 #  define PY_TIMEOUT_MAX (LLONG_MAX / 1000)
49 #elif defined (NT_THREADS)
50    // WaitForSingleObject() accepts timeout in milliseconds in the range
51    // [0; 0xFFFFFFFE] (DWORD type). INFINITE value (0xFFFFFFFF) means no
52    // timeout. 0xFFFFFFFE milliseconds is around 49.7 days.
53 #  if 0xFFFFFFFELL * 1000 < LLONG_MAX
54 #    define PY_TIMEOUT_MAX (0xFFFFFFFELL * 1000)
55 #  else
56 #    define PY_TIMEOUT_MAX LLONG_MAX
57 #  endif
58 #else
59 #  define PY_TIMEOUT_MAX LLONG_MAX
60 #endif
61 
62 
63 /* If microseconds == 0, the call is non-blocking: it returns immediately
64    even when the lock can't be acquired.
65    If microseconds > 0, the call waits up to the specified duration.
66    If microseconds < 0, the call waits until success (or abnormal failure)
67 
68    microseconds must be less than PY_TIMEOUT_MAX. Behaviour otherwise is
69    undefined.
70 
71    If intr_flag is true and the acquire is interrupted by a signal, then the
72    call will return PY_LOCK_INTR.  The caller may reattempt to acquire the
73    lock.
74 */
75 PyAPI_FUNC(PyLockStatus) PyThread_acquire_lock_timed(PyThread_type_lock,
76                                                      PY_TIMEOUT_T microseconds,
77                                                      int intr_flag);
78 
79 PyAPI_FUNC(void) PyThread_release_lock(PyThread_type_lock);
80 
81 PyAPI_FUNC(size_t) PyThread_get_stacksize(void);
82 PyAPI_FUNC(int) PyThread_set_stacksize(size_t);
83 
84 #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000
85 PyAPI_FUNC(PyObject*) PyThread_GetInfo(void);
86 #endif
87 
88 
89 /* Thread Local Storage (TLS) API
90    TLS API is DEPRECATED.  Use Thread Specific Storage (TSS) API.
91 
92    The existing TLS API has used int to represent TLS keys across all
93    platforms, but it is not POSIX-compliant.  Therefore, the new TSS API uses
94    opaque data type to represent TSS keys to be compatible (see PEP 539).
95 */
96 Py_DEPRECATED(3.7) PyAPI_FUNC(int) PyThread_create_key(void);
97 Py_DEPRECATED(3.7) PyAPI_FUNC(void) PyThread_delete_key(int key);
98 Py_DEPRECATED(3.7) PyAPI_FUNC(int) PyThread_set_key_value(int key,
99                                                           void *value);
100 Py_DEPRECATED(3.7) PyAPI_FUNC(void *) PyThread_get_key_value(int key);
101 Py_DEPRECATED(3.7) PyAPI_FUNC(void) PyThread_delete_key_value(int key);
102 
103 /* Cleanup after a fork */
104 Py_DEPRECATED(3.7) PyAPI_FUNC(void) PyThread_ReInitTLS(void);
105 
106 
107 #if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000
108 /* New in 3.7 */
109 /* Thread Specific Storage (TSS) API */
110 
111 typedef struct _Py_tss_t Py_tss_t;  /* opaque */
112 
113 PyAPI_FUNC(Py_tss_t *) PyThread_tss_alloc(void);
114 PyAPI_FUNC(void) PyThread_tss_free(Py_tss_t *key);
115 
116 /* The parameter key must not be NULL. */
117 PyAPI_FUNC(int) PyThread_tss_is_created(Py_tss_t *key);
118 PyAPI_FUNC(int) PyThread_tss_create(Py_tss_t *key);
119 PyAPI_FUNC(void) PyThread_tss_delete(Py_tss_t *key);
120 PyAPI_FUNC(int) PyThread_tss_set(Py_tss_t *key, void *value);
121 PyAPI_FUNC(void *) PyThread_tss_get(Py_tss_t *key);
122 #endif  /* New in 3.7 */
123 
124 #ifndef Py_LIMITED_API
125 #  define Py_CPYTHON_PYTHREAD_H
126 #  include "cpython/pythread.h"
127 #  undef Py_CPYTHON_PYTHREAD_H
128 #endif
129 
130 #ifdef __cplusplus
131 }
132 #endif
133 #endif /* !Py_PYTHREAD_H */
134