1 2 /* Thread package. 3 This is intended to be usable independently from Python. 4 The implementation for system foobar is in a file thread_foobar.h 5 which is included by this file dependent on config settings. 6 Stuff shared by all thread_*.h files is collected here. */ 7 8 #include "Python.h" 9 10 #ifndef _POSIX_THREADS 11 /* This means pthreads are not implemented in libc headers, hence the macro 12 not present in unistd.h. But they still can be implemented as an external 13 library (e.g. gnu pth in pthread emulation) */ 14 # ifdef HAVE_PTHREAD_H 15 # include <pthread.h> /* _POSIX_THREADS */ 16 # endif 17 #endif 18 19 #ifndef DONT_HAVE_STDIO_H 20 #include <stdio.h> 21 #endif 22 23 #include <stdlib.h> 24 25 #include "pythread.h" 26 27 #ifndef _POSIX_THREADS 28 29 /* Check if we're running on HP-UX and _SC_THREADS is defined. If so, then 30 enough of the Posix threads package is implemented to support python 31 threads. 32 33 This is valid for HP-UX 11.23 running on an ia64 system. If needed, add 34 a check of __ia64 to verify that we're running on an ia64 system instead 35 of a pa-risc system. 36 */ 37 #ifdef __hpux 38 #ifdef _SC_THREADS 39 #define _POSIX_THREADS 40 #endif 41 #endif 42 43 #endif /* _POSIX_THREADS */ 44 45 46 #ifdef Py_DEBUG 47 static int thread_debug = 0; 48 #define dprintf(args) (void)((thread_debug & 1) && printf args) 49 #define d2printf(args) ((thread_debug & 8) && printf args) 50 #else 51 #define dprintf(args) 52 #define d2printf(args) 53 #endif 54 55 static int initialized; 56 57 static void PyThread__init_thread(void); /* Forward */ 58 59 void 60 PyThread_init_thread(void) 61 { 62 #ifdef Py_DEBUG 63 char *p = Py_GETENV("PYTHONTHREADDEBUG"); 64 65 if (p) { 66 if (*p) 67 thread_debug = atoi(p); 68 else 69 thread_debug = 1; 70 } 71 #endif /* Py_DEBUG */ 72 if (initialized) 73 return; 74 initialized = 1; 75 dprintf(("PyThread_init_thread called\n")); 76 PyThread__init_thread(); 77 } 78 79 /* Support for runtime thread stack size tuning. 80 A value of 0 means using the platform's default stack size 81 or the size specified by the THREAD_STACK_SIZE macro. */ 82 static size_t _pythread_stacksize = 0; 83 84 #ifdef _POSIX_THREADS 85 #define PYTHREAD_NAME "pthread" 86 #include "thread_pthread.h" 87 #endif 88 89 #ifdef NT_THREADS 90 #define PYTHREAD_NAME "nt" 91 #include "thread_nt.h" 92 #endif 93 94 95 /* 96 #ifdef FOOBAR_THREADS 97 #include "thread_foobar.h" 98 #endif 99 */ 100 101 /* return the current thread stack size */ 102 size_t 103 PyThread_get_stacksize(void) 104 { 105 return _pythread_stacksize; 106 } 107 108 /* Only platforms defining a THREAD_SET_STACKSIZE() macro 109 in thread_<platform>.h support changing the stack size. 110 Return 0 if stack size is valid, 111 -1 if stack size value is invalid, 112 -2 if setting stack size is not supported. */ 113 int 114 PyThread_set_stacksize(size_t size) 115 { 116 #if defined(THREAD_SET_STACKSIZE) 117 return THREAD_SET_STACKSIZE(size); 118 #else 119 return -2; 120 #endif 121 } 122 123 #ifndef Py_HAVE_NATIVE_TLS 124 /* If the platform has not supplied a platform specific 125 TLS implementation, provide our own. 126 127 This code stolen from "thread_sgi.h", where it was the only 128 implementation of an existing Python TLS API. 129 */ 130 /* ------------------------------------------------------------------------ 131 Per-thread data ("key") support. 132 133 Use PyThread_create_key() to create a new key. This is typically shared 134 across threads. 135 136 Use PyThread_set_key_value(thekey, value) to associate void* value with 137 thekey in the current thread. Each thread has a distinct mapping of thekey 138 to a void* value. Caution: if the current thread already has a mapping 139 for thekey, value is ignored. 140 141 Use PyThread_get_key_value(thekey) to retrieve the void* value associated 142 with thekey in the current thread. This returns NULL if no value is 143 associated with thekey in the current thread. 144 145 Use PyThread_delete_key_value(thekey) to forget the current thread's associated 146 value for thekey. PyThread_delete_key(thekey) forgets the values associated 147 with thekey across *all* threads. 148 149 While some of these functions have error-return values, none set any 150 Python exception. 151 152 None of the functions does memory management on behalf of the void* values. 153 You need to allocate and deallocate them yourself. If the void* values 154 happen to be PyObject*, these functions don't do refcount operations on 155 them either. 156 157 The GIL does not need to be held when calling these functions; they supply 158 their own locking. This isn't true of PyThread_create_key(), though (see 159 next paragraph). 160 161 There's a hidden assumption that PyThread_create_key() will be called before 162 any of the other functions are called. There's also a hidden assumption 163 that calls to PyThread_create_key() are serialized externally. 164 ------------------------------------------------------------------------ */ 165 166 /* A singly-linked list of struct key objects remembers all the key->value 167 * associations. File static keyhead heads the list. keymutex is used 168 * to enforce exclusion internally. 169 */ 170 struct key { 171 /* Next record in the list, or NULL if this is the last record. */ 172 struct key *next; 173 174 /* The thread id, according to PyThread_get_thread_ident(). */ 175 long id; 176 177 /* The key and its associated value. */ 178 int key; 179 void *value; 180 }; 181 182 static struct key *keyhead = NULL; 183 static PyThread_type_lock keymutex = NULL; 184 static int nkeys = 0; /* PyThread_create_key() hands out nkeys+1 next */ 185 186 /* Internal helper. 187 * If the current thread has a mapping for key, the appropriate struct key* 188 * is returned. NB: value is ignored in this case! 189 * If there is no mapping for key in the current thread, then: 190 * If value is NULL, NULL is returned. 191 * Else a mapping of key to value is created for the current thread, 192 * and a pointer to a new struct key* is returned; except that if 193 * malloc() can't find room for a new struct key*, NULL is returned. 194 * So when value==NULL, this acts like a pure lookup routine, and when 195 * value!=NULL, this acts like dict.setdefault(), returning an existing 196 * mapping if one exists, else creating a new mapping. 197 * 198 * Caution: this used to be too clever, trying to hold keymutex only 199 * around the "p->next = keyhead; keyhead = p" pair. That allowed 200 * another thread to mutate the list, via key deletion, concurrent with 201 * find_key() crawling over the list. Hilarity ensued. For example, when 202 * the for-loop here does "p = p->next", p could end up pointing at a 203 * record that PyThread_delete_key_value() was concurrently free()'ing. 204 * That could lead to anything, from failing to find a key that exists, to 205 * segfaults. Now we lock the whole routine. 206 */ 207 static struct key * 208 find_key(int set_value, int key, void *value) 209 { 210 struct key *p, *prev_p; 211 long id = PyThread_get_thread_ident(); 212 213 if (!keymutex) 214 return NULL; 215 PyThread_acquire_lock(keymutex, 1); 216 prev_p = NULL; 217 for (p = keyhead; p != NULL; p = p->next) { 218 if (p->id == id && p->key == key) { 219 if (set_value) 220 p->value = value; 221 goto Done; 222 } 223 /* Sanity check. These states should never happen but if 224 * they do we must abort. Otherwise we'll end up spinning 225 * in a tight loop with the lock held. A similar check is done 226 * in pystate.c tstate_delete_common(). */ 227 if (p == prev_p) 228 Py_FatalError("tls find_key: small circular list(!)"); 229 prev_p = p; 230 if (p->next == keyhead) 231 Py_FatalError("tls find_key: circular list(!)"); 232 } 233 if (!set_value && value == NULL) { 234 assert(p == NULL); 235 goto Done; 236 } 237 p = (struct key *)PyMem_RawMalloc(sizeof(struct key)); 238 if (p != NULL) { 239 p->id = id; 240 p->key = key; 241 p->value = value; 242 p->next = keyhead; 243 keyhead = p; 244 } 245 Done: 246 PyThread_release_lock(keymutex); 247 return p; 248 } 249 250 /* Return a new key. This must be called before any other functions in 251 * this family, and callers must arrange to serialize calls to this 252 * function. No violations are detected. 253 */ 254 int 255 PyThread_create_key(void) 256 { 257 /* All parts of this function are wrong if it's called by multiple 258 * threads simultaneously. 259 */ 260 if (keymutex == NULL) 261 keymutex = PyThread_allocate_lock(); 262 return ++nkeys; 263 } 264 265 /* Forget the associations for key across *all* threads. */ 266 void 267 PyThread_delete_key(int key) 268 { 269 struct key *p, **q; 270 271 PyThread_acquire_lock(keymutex, 1); 272 q = &keyhead; 273 while ((p = *q) != NULL) { 274 if (p->key == key) { 275 *q = p->next; 276 PyMem_RawFree((void *)p); 277 /* NB This does *not* free p->value! */ 278 } 279 else 280 q = &p->next; 281 } 282 PyThread_release_lock(keymutex); 283 } 284 285 int 286 PyThread_set_key_value(int key, void *value) 287 { 288 struct key *p; 289 290 p = find_key(1, key, value); 291 if (p == NULL) 292 return -1; 293 else 294 return 0; 295 } 296 297 /* Retrieve the value associated with key in the current thread, or NULL 298 * if the current thread doesn't have an association for key. 299 */ 300 void * 301 PyThread_get_key_value(int key) 302 { 303 struct key *p = find_key(0, key, NULL); 304 305 if (p == NULL) 306 return NULL; 307 else 308 return p->value; 309 } 310 311 /* Forget the current thread's association for key, if any. */ 312 void 313 PyThread_delete_key_value(int key) 314 { 315 long id = PyThread_get_thread_ident(); 316 struct key *p, **q; 317 318 PyThread_acquire_lock(keymutex, 1); 319 q = &keyhead; 320 while ((p = *q) != NULL) { 321 if (p->key == key && p->id == id) { 322 *q = p->next; 323 PyMem_RawFree((void *)p); 324 /* NB This does *not* free p->value! */ 325 break; 326 } 327 else 328 q = &p->next; 329 } 330 PyThread_release_lock(keymutex); 331 } 332 333 /* Forget everything not associated with the current thread id. 334 * This function is called from PyOS_AfterFork(). It is necessary 335 * because other thread ids which were in use at the time of the fork 336 * may be reused for new threads created in the forked process. 337 */ 338 void 339 PyThread_ReInitTLS(void) 340 { 341 long id = PyThread_get_thread_ident(); 342 struct key *p, **q; 343 344 if (!keymutex) 345 return; 346 347 /* As with interpreter_lock in PyEval_ReInitThreads() 348 we just create a new lock without freeing the old one */ 349 keymutex = PyThread_allocate_lock(); 350 351 /* Delete all keys which do not match the current thread id */ 352 q = &keyhead; 353 while ((p = *q) != NULL) { 354 if (p->id != id) { 355 *q = p->next; 356 PyMem_RawFree((void *)p); 357 /* NB This does *not* free p->value! */ 358 } 359 else 360 q = &p->next; 361 } 362 } 363 364 #endif /* Py_HAVE_NATIVE_TLS */ 365 366 PyDoc_STRVAR(threadinfo__doc__, 367 "sys.thread_info\n\ 368 \n\ 369 A struct sequence holding information about the thread implementation."); 370 371 static PyStructSequence_Field threadinfo_fields[] = { 372 {"name", "name of the thread implementation"}, 373 {"lock", "name of the lock implementation"}, 374 {"version", "name and version of the thread library"}, 375 {0} 376 }; 377 378 static PyStructSequence_Desc threadinfo_desc = { 379 "sys.thread_info", /* name */ 380 threadinfo__doc__, /* doc */ 381 threadinfo_fields, /* fields */ 382 3 383 }; 384 385 static PyTypeObject ThreadInfoType; 386 387 PyObject* 388 PyThread_GetInfo(void) 389 { 390 PyObject *threadinfo, *value; 391 int pos = 0; 392 #if (defined(_POSIX_THREADS) && defined(HAVE_CONFSTR) \ 393 && defined(_CS_GNU_LIBPTHREAD_VERSION)) 394 char buffer[255]; 395 int len; 396 #endif 397 398 if (ThreadInfoType.tp_name == 0) { 399 if (PyStructSequence_InitType2(&ThreadInfoType, &threadinfo_desc) < 0) 400 return NULL; 401 } 402 403 threadinfo = PyStructSequence_New(&ThreadInfoType); 404 if (threadinfo == NULL) 405 return NULL; 406 407 value = PyUnicode_FromString(PYTHREAD_NAME); 408 if (value == NULL) { 409 Py_DECREF(threadinfo); 410 return NULL; 411 } 412 PyStructSequence_SET_ITEM(threadinfo, pos++, value); 413 414 #ifdef _POSIX_THREADS 415 #ifdef USE_SEMAPHORES 416 value = PyUnicode_FromString("semaphore"); 417 #else 418 value = PyUnicode_FromString("mutex+cond"); 419 #endif 420 if (value == NULL) { 421 Py_DECREF(threadinfo); 422 return NULL; 423 } 424 #else 425 Py_INCREF(Py_None); 426 value = Py_None; 427 #endif 428 PyStructSequence_SET_ITEM(threadinfo, pos++, value); 429 430 #if (defined(_POSIX_THREADS) && defined(HAVE_CONFSTR) \ 431 && defined(_CS_GNU_LIBPTHREAD_VERSION)) 432 value = NULL; 433 len = confstr(_CS_GNU_LIBPTHREAD_VERSION, buffer, sizeof(buffer)); 434 if (1 < len && (size_t)len < sizeof(buffer)) { 435 value = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1); 436 if (value == NULL) 437 PyErr_Clear(); 438 } 439 if (value == NULL) 440 #endif 441 { 442 Py_INCREF(Py_None); 443 value = Py_None; 444 } 445 PyStructSequence_SET_ITEM(threadinfo, pos++, value); 446 return threadinfo; 447 } 448