1 /**
2   Mirror _pythread.h
3   */
4 module deimos.python.pythread;
5 
6 import deimos.python.pyport;
7 
8 extern(C):
9 // Python-header-file: Include/pythread.h:
10 
11 version(Python_3_2_Or_Later) {
12     /** Return status codes for Python lock acquisition.  Chosen for maximum
13      * backwards compatibility, ie failure -> 0, success -> 1.  */
14     /// Availability: >= 3.2
15     enum PyLockStatus {
16         /// _
17         PY_LOCK_FAILURE = 0,
18         /// _
19         PY_LOCK_ACQUIRED = 1,
20         /// _
21         PY_LOCK_INTR
22     }
23 }
24 
25 version(Python_3_7_Or_Later) {
26     /// _
27     enum PYTHREAD_INVALID_THREAD_ID = -1;
28 }
29 
30 /// _
31 alias void* PyThread_type_lock;
32 /// _
33 alias void* PyThread_type_sema;
34 
35 /// _
36 void PyThread_init_thread();
37 version(Python_3_7_Or_Later) {
38     /// _
39     C_ulong PyThread_start_new_thread(void function(void*), void*);
40 }else{
41     /// _
42     C_long PyThread_start_new_thread(void function(void*), void*);
43 }
44 /// _
45 void PyThread_exit_thread();
46 /// _
47 void PyThread__PyThread_exit_thread();
48 version(Python_3_7_Or_Later) {
49     /// _
50     C_ulong PyThread_get_thread_ident();
51 }else{
52     /// _
53     C_long PyThread_get_thread_ident();
54 }
55 
56 /// _
57 PyThread_type_lock PyThread_allocate_lock();
58 /// _
59 void PyThread_free_lock(PyThread_type_lock);
60 /// _
61 int PyThread_acquire_lock(PyThread_type_lock, int);
62 /// _
63 enum WAIT_LOCK = 1;
64 /// _
65 enum NOWAIT_LOCK = 0;
66 version(Python_3_2_Or_Later) {
67     /** PY_TIMEOUT_T is the integral type used to specify timeouts when waiting
68        on a lock (see PyThread_acquire_lock_timed() below).
69        PY_TIMEOUT_MAX is the highest usable value (in microseconds) of that
70        type, and depends on the system threading API.
71 
72         NOTE: this isn't the same value as `_thread.TIMEOUT_MAX`.  The _thread
73         module exposes a higher-level API, with timeouts expressed in seconds
74         and floating-point numbers allowed.
75      */
76     /// Availability: >= 3.2
77     alias C_long PY_TIMEOUT_T;
78 
79     /* In the NT API, the timeout is a DWORD and is expressed in milliseconds */
80     /+ ??
81 #if defined (NT_THREADS)
82 #if (Py_LL(0xFFFFFFFF) * 1000 < PY_TIMEOUT_MAX)
83 #undef PY_TIMEOUT_MAX
84 #define PY_TIMEOUT_MAX (Py_LL(0xFFFFFFFF) * 1000)
85 #endif
86 #endif
87         +/
88 
89         /* If microseconds == 0, the call is non-blocking: it returns immediately
90        even when the lock can't be acquired.
91        If microseconds > 0, the call waits up to the specified duration.
92        If microseconds < 0, the call waits until success (or abnormal failure)
93 
94        microseconds must be less than PY_TIMEOUT_MAX. Behaviour otherwise is
95        undefined.
96 
97        If intr_flag is true and the acquire is interrupted by a signal, then the
98        call will return PY_LOCK_INTR.  The caller may reattempt to acquire the
99        lock.
100      */
101     /// Availability: >= 3.2
102         PyLockStatus PyThread_acquire_lock_timed(
103             PyThread_type_lock,
104             PY_TIMEOUT_T microseconds,
105             int intr_flag);
106 
107 }
108 /// _
109 void PyThread_release_lock(PyThread_type_lock);
110 
111 version(Python_2_5_Or_Later){
112     /// Availability: >= 2.5
113     size_t PyThread_get_stacksize();
114     /// Availability: >= 2.5
115     int PyThread_set_stacksize(size_t);
116 }
117 
118 /// _
119 void PyThread_exit_prog(int);
120 /// _
121 void PyThread__PyThread_exit_prog(int);
122 
123 /// _
124 int PyThread_create_key();
125 /// _
126 void PyThread_delete_key(int);
127 /// _
128 int PyThread_set_key_value(int, void*);
129 /// _
130 void* PyThread_get_key_value(int);
131 /// _
132 void PyThread_delete_key_value(int key);
133 
134 version(Python_2_5_Or_Later) {
135     /// Availability: >= 2.5
136     void PyThread_ReInitTLS();
137 }
138 
139 version(Python_3_7_Or_Later) {
140     version(Posix) {
141         import core.sys.posix.pthread;
142 
143         alias pthread_key_t NATIVE_TSS_KEY_T;
144     }else {
145         alias C_ulong NATIVE_TSS_KEY_T;
146     }
147 
148     struct Py_tss_t {
149         int _is_initialized;
150         NATIVE_TSS_KEY_T _key;
151     }
152 
153     enum Py_tss_NEEDS_INIT = 0;
154 
155     Py_tss_t* PyThread_tss_alloc();
156     void PyThread_tss_free(Py_tss_t* key);
157 
158     int PyThread_tss_is_created(Py_tss_t* key);
159     int PyThread_tss_create(Py_tss_t* key);
160     void PyThread_tss_delete(Py_tss_t* key);
161     int PyThread_tss_set(Py_tss_t* key, void* value);
162     void* PyThread_tss_get(Py_tss_t* key);
163 }