blob: bb9d86412218ad24b189f7b8e221e56e4491b26c [file] [log] [blame]
Guido van Rossum1984f1e1992-08-04 12:41:02 +00001
Fred Drake3cf4d2b2000-07-09 00:55:06 +00002#ifndef Py_PYTHREAD_H
3#define Py_PYTHREAD_H
4
Guido van Rossum65d5b571998-12-21 19:32:43 +00005typedef void *PyThread_type_lock;
Sjoerd Mullenderd10d8291992-09-11 15:19:27 +00006
7#ifdef __cplusplus
8extern "C" {
9#endif
10
Antoine Pitrou810023d2010-12-15 22:59:16 +000011/* Return status codes for Python lock acquisition. Chosen for maximum
12 * backwards compatibility, ie failure -> 0, success -> 1. */
13typedef enum PyLockStatus {
14 PY_LOCK_FAILURE = 0,
15 PY_LOCK_ACQUIRED = 1,
16 PY_LOCK_INTR
17} PyLockStatus;
18
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +020019#ifndef Py_LIMITED_API
20#define PYTHREAD_INVALID_THREAD_ID ((unsigned long)-1)
21#endif
22
Mark Hammond91a681d2002-08-12 07:21:58 +000023PyAPI_FUNC(void) PyThread_init_thread(void);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +020024PyAPI_FUNC(unsigned long) PyThread_start_new_thread(void (*)(void *), void *);
Victor Stinnerc664b342019-05-04 11:48:05 -040025PyAPI_FUNC(void) _Py_NO_RETURN PyThread_exit_thread(void);
Serhiy Storchakaaefa7eb2017-03-23 15:48:39 +020026PyAPI_FUNC(unsigned long) PyThread_get_thread_ident(void);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000027
Michael Feltd0eeb932019-06-14 00:34:46 +020028#if defined(__APPLE__) || defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(_WIN32) || defined(_AIX)
Jake Teslerb121f632019-05-22 08:43:17 -070029#define PY_HAVE_THREAD_NATIVE_ID
30PyAPI_FUNC(unsigned long) PyThread_get_thread_native_id(void);
31#endif
32
Mark Hammond91a681d2002-08-12 07:21:58 +000033PyAPI_FUNC(PyThread_type_lock) PyThread_allocate_lock(void);
34PyAPI_FUNC(void) PyThread_free_lock(PyThread_type_lock);
35PyAPI_FUNC(int) PyThread_acquire_lock(PyThread_type_lock, int);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +090036#define WAIT_LOCK 1
37#define NOWAIT_LOCK 0
Antoine Pitrou7c3e5772010-04-14 15:44:10 +000038
Victor Stinner87255be2020-04-07 23:11:49 +020039#ifndef Py_LIMITED_API
40#ifdef HAVE_FORK
41/* Private function to reinitialize a lock at fork in the child process.
42 Reset the lock to the unlocked state.
43 Return 0 on success, return -1 on error. */
44PyAPI_FUNC(int) _PyThread_at_fork_reinit(PyThread_type_lock *lock);
45#endif /* HAVE_FORK */
46#endif /* !Py_LIMITED_API */
47
Antoine Pitrou7c3e5772010-04-14 15:44:10 +000048/* PY_TIMEOUT_T is the integral type used to specify timeouts when waiting
49 on a lock (see PyThread_acquire_lock_timed() below).
50 PY_TIMEOUT_MAX is the highest usable value (in microseconds) of that
51 type, and depends on the system threading API.
Victor Stinner754851f2011-04-19 23:58:51 +020052
Antoine Pitrou7c3e5772010-04-14 15:44:10 +000053 NOTE: this isn't the same value as `_thread.TIMEOUT_MAX`. The _thread
54 module exposes a higher-level API, with timeouts expressed in seconds
55 and floating-point numbers allowed.
56*/
Benjamin Petersonaf580df2016-09-06 10:46:49 -070057#define PY_TIMEOUT_T long long
Antoine Pitrou7c3e5772010-04-14 15:44:10 +000058
Victor Stinner850a18e2017-10-24 16:53:32 -070059#if defined(_POSIX_THREADS)
60 /* PyThread_acquire_lock_timed() uses _PyTime_FromNanoseconds(us * 1000),
61 convert microseconds to nanoseconds. */
Sergey Fedoseev1f9f69d2019-12-05 19:55:28 +050062# define PY_TIMEOUT_MAX (LLONG_MAX / 1000)
Victor Stinner850a18e2017-10-24 16:53:32 -070063#elif defined (NT_THREADS)
64 /* In the NT API, the timeout is a DWORD and is expressed in milliseconds */
Sergey Fedoseev1f9f69d2019-12-05 19:55:28 +050065# if 0xFFFFFFFFLL * 1000 < LLONG_MAX
Victor Stinner850a18e2017-10-24 16:53:32 -070066# define PY_TIMEOUT_MAX (0xFFFFFFFFLL * 1000)
67# else
Sergey Fedoseev1f9f69d2019-12-05 19:55:28 +050068# define PY_TIMEOUT_MAX LLONG_MAX
Victor Stinner850a18e2017-10-24 16:53:32 -070069# endif
70#else
Sergey Fedoseev1f9f69d2019-12-05 19:55:28 +050071# define PY_TIMEOUT_MAX LLONG_MAX
Antoine Pitrou7c3e5772010-04-14 15:44:10 +000072#endif
Victor Stinner850a18e2017-10-24 16:53:32 -070073
Antoine Pitrou7c3e5772010-04-14 15:44:10 +000074
75/* If microseconds == 0, the call is non-blocking: it returns immediately
76 even when the lock can't be acquired.
77 If microseconds > 0, the call waits up to the specified duration.
78 If microseconds < 0, the call waits until success (or abnormal failure)
Antoine Pitrou810023d2010-12-15 22:59:16 +000079
Antoine Pitrou7c3e5772010-04-14 15:44:10 +000080 microseconds must be less than PY_TIMEOUT_MAX. Behaviour otherwise is
Antoine Pitrou810023d2010-12-15 22:59:16 +000081 undefined.
82
83 If intr_flag is true and the acquire is interrupted by a signal, then the
84 call will return PY_LOCK_INTR. The caller may reattempt to acquire the
85 lock.
86*/
87PyAPI_FUNC(PyLockStatus) PyThread_acquire_lock_timed(PyThread_type_lock,
88 PY_TIMEOUT_T microseconds,
89 int intr_flag);
90
Mark Hammond91a681d2002-08-12 07:21:58 +000091PyAPI_FUNC(void) PyThread_release_lock(PyThread_type_lock);
Guido van Rossum1984f1e1992-08-04 12:41:02 +000092
Thomas Wouters0e3f5912006-08-11 14:57:12 +000093PyAPI_FUNC(size_t) PyThread_get_stacksize(void);
94PyAPI_FUNC(int) PyThread_set_stacksize(size_t);
95
Serhiy Storchaka34d0ac82016-12-27 14:57:39 +020096#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03030000
Victor Stinnerd5c355c2011-04-30 14:53:09 +020097PyAPI_FUNC(PyObject*) PyThread_GetInfo(void);
Serhiy Storchaka34d0ac82016-12-27 14:57:39 +020098#endif
Victor Stinner754851f2011-04-19 23:58:51 +020099
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900100
101/* Thread Local Storage (TLS) API
102 TLS API is DEPRECATED. Use Thread Specific Storage (TSS) API.
103
104 The existing TLS API has used int to represent TLS keys across all
105 platforms, but it is not POSIX-compliant. Therefore, the new TSS API uses
106 opaque data type to represent TSS keys to be compatible (see PEP 539).
107*/
Zackery Spytz3c8724f2019-05-28 09:16:33 -0600108Py_DEPRECATED(3.7) PyAPI_FUNC(int) PyThread_create_key(void);
109Py_DEPRECATED(3.7) PyAPI_FUNC(void) PyThread_delete_key(int key);
110Py_DEPRECATED(3.7) PyAPI_FUNC(int) PyThread_set_key_value(int key,
111 void *value);
112Py_DEPRECATED(3.7) PyAPI_FUNC(void *) PyThread_get_key_value(int key);
113Py_DEPRECATED(3.7) PyAPI_FUNC(void) PyThread_delete_key_value(int key);
Guido van Rossuma027efa1997-05-05 20:56:21 +0000114
Benjamin Petersone68df0f2008-06-13 00:26:50 +0000115/* Cleanup after a fork */
Zackery Spytz3c8724f2019-05-28 09:16:33 -0600116Py_DEPRECATED(3.7) PyAPI_FUNC(void) PyThread_ReInitTLS(void);
Masayuki Yamamoto731e1892017-10-06 19:41:34 +0900117
118
119#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03070000
120/* New in 3.7 */
121/* Thread Specific Storage (TSS) API */
122
123typedef struct _Py_tss_t Py_tss_t; /* opaque */
124
125#ifndef Py_LIMITED_API
126#if defined(_POSIX_THREADS)
127 /* Darwin needs pthread.h to know type name the pthread_key_t. */
128# include <pthread.h>
129# define NATIVE_TSS_KEY_T pthread_key_t
130#elif defined(NT_THREADS)
131 /* In Windows, native TSS key type is DWORD,
132 but hardcode the unsigned long to avoid errors for include directive.
133 */
134# define NATIVE_TSS_KEY_T unsigned long
135#else
136# error "Require native threads. See https://bugs.python.org/issue31370"
137#endif
138
139/* When Py_LIMITED_API is not defined, the type layout of Py_tss_t is
140 exposed to allow static allocation in the API clients. Even in this case,
141 you must handle TSS keys through API functions due to compatibility.
142*/
143struct _Py_tss_t {
144 int _is_initialized;
145 NATIVE_TSS_KEY_T _key;
146};
147
148#undef NATIVE_TSS_KEY_T
149
150/* When static allocation, you must initialize with Py_tss_NEEDS_INIT. */
151#define Py_tss_NEEDS_INIT {0}
152#endif /* !Py_LIMITED_API */
153
154PyAPI_FUNC(Py_tss_t *) PyThread_tss_alloc(void);
155PyAPI_FUNC(void) PyThread_tss_free(Py_tss_t *key);
156
157/* The parameter key must not be NULL. */
158PyAPI_FUNC(int) PyThread_tss_is_created(Py_tss_t *key);
159PyAPI_FUNC(int) PyThread_tss_create(Py_tss_t *key);
160PyAPI_FUNC(void) PyThread_tss_delete(Py_tss_t *key);
161PyAPI_FUNC(int) PyThread_tss_set(Py_tss_t *key, void *value);
162PyAPI_FUNC(void *) PyThread_tss_get(Py_tss_t *key);
163#endif /* New in 3.7 */
Benjamin Petersone68df0f2008-06-13 00:26:50 +0000164
Sjoerd Mullenderd10d8291992-09-11 15:19:27 +0000165#ifdef __cplusplus
166}
167#endif
168
Guido van Rossumd023a781999-03-24 19:02:09 +0000169#endif /* !Py_PYTHREAD_H */