14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Thread package. 34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm This is intended to be usable independently from Python. 44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm The implementation for system foobar is in a file thread_foobar.h 54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm which is included by this file dependent on config settings. 64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Stuff shared by all thread_*.h files is collected here. */ 74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "Python.h" 94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifndef _POSIX_THREADS 124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* This means pthreads are not implemented in libc headers, hence the macro 134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm not present in unistd.h. But they still can be implemented as an external 144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm library (e.g. gnu pth in pthread emulation) */ 154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# ifdef HAVE_PTHREAD_H 164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# include <pthread.h> /* _POSIX_THREADS */ 174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm# endif 184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifndef DONT_HAVE_STDIO_H 214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include <stdio.h> 224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include <stdlib.h> 254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef __sgi 274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifndef HAVE_PTHREAD_H /* XXX Need to check in configure.in */ 284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#undef _POSIX_THREADS 294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "pythread.h" 334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifndef _POSIX_THREADS 354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef __sgi 374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define SGI_THREADS 384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef HAVE_THREAD_H 414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define SOLARIS_THREADS 424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#if defined(sun) && !defined(SOLARIS_THREADS) 454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define SUN_LWP 464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Check if we're running on HP-UX and _SC_THREADS is defined. If so, then 494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm enough of the Posix threads package is implemented to support python 504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm threads. 514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm This is valid for HP-UX 11.23 running on an ia64 system. If needed, add 534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm a check of __ia64 to verify that we're running on a ia64 system instead 544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm of a pa-risc system. 554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm*/ 564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef __hpux 574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef _SC_THREADS 584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define _POSIX_THREADS 594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif /* _POSIX_THREADS */ 634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef Py_DEBUG 664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int thread_debug = 0; 674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define dprintf(args) (void)((thread_debug & 1) && printf args) 684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define d2printf(args) ((thread_debug & 8) && printf args) 694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#else 704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define dprintf(args) 714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define d2printf(args) 724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int initialized; 754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic void PyThread__init_thread(void); /* Forward */ 774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmvoid 794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyThread_init_thread(void) 804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef Py_DEBUG 824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm char *p = Py_GETENV("PYTHONTHREADDEBUG"); 834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (p) { 854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (*p) 864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm thread_debug = atoi(p); 874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else 884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm thread_debug = 1; 894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif /* Py_DEBUG */ 914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (initialized) 924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return; 934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm initialized = 1; 944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dprintf(("PyThread_init_thread called\n")); 954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyThread__init_thread(); 964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Support for runtime thread stack size tuning. 994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm A value of 0 means using the platform's default stack size 1004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm or the size specified by the THREAD_STACK_SIZE macro. */ 1014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic size_t _pythread_stacksize = 0; 1024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef SGI_THREADS 1044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "thread_sgi.h" 1054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 1064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef SOLARIS_THREADS 1084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "thread_solaris.h" 1094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 1104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef SUN_LWP 1124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "thread_lwp.h" 1134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 1144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef HAVE_PTH 1164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "thread_pth.h" 1174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#undef _POSIX_THREADS 1184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 1194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef _POSIX_THREADS 1214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "thread_pthread.h" 1224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 1234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef C_THREADS 1254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "thread_cthread.h" 1264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 1274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef NT_THREADS 1294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "thread_nt.h" 1304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 1314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef OS2_THREADS 1334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "thread_os2.h" 1344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 1354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef BEOS_THREADS 1374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "thread_beos.h" 1384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 1394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef PLAN9_THREADS 1414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "thread_plan9.h" 1424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 1434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef ATHEOS_THREADS 1454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "thread_atheos.h" 1464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 1474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* 1494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef FOOBAR_THREADS 1504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "thread_foobar.h" 1514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 1524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm*/ 1534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* return the current thread stack size */ 1554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmsize_t 1564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyThread_get_stacksize(void) 1574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 1584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return _pythread_stacksize; 1594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 1604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Only platforms defining a THREAD_SET_STACKSIZE() macro 1624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm in thread_<platform>.h support changing the stack size. 1634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Return 0 if stack size is valid, 1644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm -1 if stack size value is invalid, 1654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm -2 if setting stack size is not supported. */ 1664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmint 1674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyThread_set_stacksize(size_t size) 1684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 1694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#if defined(THREAD_SET_STACKSIZE) 1704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return THREAD_SET_STACKSIZE(size); 1714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#else 1724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -2; 1734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 1744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 1754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifndef Py_HAVE_NATIVE_TLS 1774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* If the platform has not supplied a platform specific 1784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm TLS implementation, provide our own. 1794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm This code stolen from "thread_sgi.h", where it was the only 1814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm implementation of an existing Python TLS API. 1824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm*/ 1834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* ------------------------------------------------------------------------ 1844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPer-thread data ("key") support. 1854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmUse PyThread_create_key() to create a new key. This is typically shared 1874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmacross threads. 1884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmUse PyThread_set_key_value(thekey, value) to associate void* value with 1904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmthekey in the current thread. Each thread has a distinct mapping of thekey 1914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmto a void* value. Caution: if the current thread already has a mapping 1924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfor thekey, value is ignored. 1934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmUse PyThread_get_key_value(thekey) to retrieve the void* value associated 1954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmwith thekey in the current thread. This returns NULL if no value is 1964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmassociated with thekey in the current thread. 1974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmUse PyThread_delete_key_value(thekey) to forget the current thread's associated 1994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmvalue for thekey. PyThread_delete_key(thekey) forgets the values associated 2004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmwith thekey across *all* threads. 2014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmWhile some of these functions have error-return values, none set any 2034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPython exception. 2044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmNone of the functions does memory management on behalf of the void* values. 2064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmYou need to allocate and deallocate them yourself. If the void* values 2074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmhappen to be PyObject*, these functions don't do refcount operations on 2084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmthem either. 2094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmThe GIL does not need to be held when calling these functions; they supply 2114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtheir own locking. This isn't true of PyThread_create_key(), though (see 2124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmnext paragraph). 2134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmThere's a hidden assumption that PyThread_create_key() will be called before 2154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmany of the other functions are called. There's also a hidden assumption 2164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmthat calls to PyThread_create_key() are serialized externally. 2174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm------------------------------------------------------------------------ */ 2184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* A singly-linked list of struct key objects remembers all the key->value 2204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * associations. File static keyhead heads the list. keymutex is used 2214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * to enforce exclusion internally. 2224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 2234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstruct key { 2244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Next record in the list, or NULL if this is the last record. */ 2254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm struct key *next; 2264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* The thread id, according to PyThread_get_thread_ident(). */ 2284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm long id; 2294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* The key and its associated value. */ 2314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int key; 2324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm void *value; 2334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}; 2344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic struct key *keyhead = NULL; 2364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyThread_type_lock keymutex = NULL; 2374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int nkeys = 0; /* PyThread_create_key() hands out nkeys+1 next */ 2384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Internal helper. 2404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * If the current thread has a mapping for key, the appropriate struct key* 2414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * is returned. NB: value is ignored in this case! 2424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * If there is no mapping for key in the current thread, then: 2434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * If value is NULL, NULL is returned. 2444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * Else a mapping of key to value is created for the current thread, 2454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * and a pointer to a new struct key* is returned; except that if 2464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * malloc() can't find room for a new struct key*, NULL is returned. 2474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * So when value==NULL, this acts like a pure lookup routine, and when 2484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * value!=NULL, this acts like dict.setdefault(), returning an existing 2494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * mapping if one exists, else creating a new mapping. 2504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * 2514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * Caution: this used to be too clever, trying to hold keymutex only 2524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * around the "p->next = keyhead; keyhead = p" pair. That allowed 2534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * another thread to mutate the list, via key deletion, concurrent with 2544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * find_key() crawling over the list. Hilarity ensued. For example, when 2554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * the for-loop here does "p = p->next", p could end up pointing at a 2564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * record that PyThread_delete_key_value() was concurrently free()'ing. 2574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * That could lead to anything, from failing to find a key that exists, to 2584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * segfaults. Now we lock the whole routine. 2594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 2604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic struct key * 2614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfind_key(int key, void *value) 2624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 2634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm struct key *p, *prev_p; 2644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm long id = PyThread_get_thread_ident(); 2654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!keymutex) 2674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 2684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyThread_acquire_lock(keymutex, 1); 2694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm prev_p = NULL; 2704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for (p = keyhead; p != NULL; p = p->next) { 2714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (p->id == id && p->key == key) 2724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto Done; 2734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Sanity check. These states should never happen but if 2744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * they do we must abort. Otherwise we'll end up spinning in 2754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * in a tight loop with the lock held. A similar check is done 2764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * in pystate.c tstate_delete_common(). */ 2774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (p == prev_p) 2784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_FatalError("tls find_key: small circular list(!)"); 2794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm prev_p = p; 2804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (p->next == keyhead) 2814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Py_FatalError("tls find_key: circular list(!)"); 2824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 2834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (value == NULL) { 2844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm assert(p == NULL); 2854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm goto Done; 2864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 2874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm p = (struct key *)malloc(sizeof(struct key)); 2884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (p != NULL) { 2894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm p->id = id; 2904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm p->key = key; 2914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm p->value = value; 2924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm p->next = keyhead; 2934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm keyhead = p; 2944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 2954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm Done: 2964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyThread_release_lock(keymutex); 2974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return p; 2984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 2994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Return a new key. This must be called before any other functions in 3014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * this family, and callers must arrange to serialize calls to this 3024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * function. No violations are detected. 3034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 3044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmint 3054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyThread_create_key(void) 3064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 3074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* All parts of this function are wrong if it's called by multiple 3084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * threads simultaneously. 3094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 3104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (keymutex == NULL) 3114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm keymutex = PyThread_allocate_lock(); 3124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return ++nkeys; 3134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 3144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Forget the associations for key across *all* threads. */ 3164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmvoid 3174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyThread_delete_key(int key) 3184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 3194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm struct key *p, **q; 3204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyThread_acquire_lock(keymutex, 1); 3224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm q = &keyhead; 3234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm while ((p = *q) != NULL) { 3244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (p->key == key) { 3254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *q = p->next; 3264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm free((void *)p); 3274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* NB This does *not* free p->value! */ 3284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 3294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else 3304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm q = &p->next; 3314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 3324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyThread_release_lock(keymutex); 3334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 3344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Confusing: If the current thread has an association for key, 3364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * value is ignored, and 0 is returned. Else an attempt is made to create 3374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * an association of key to value for the current thread. 0 is returned 3384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * if that succeeds, but -1 is returned if there's not enough memory 3394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * to create the association. value must not be NULL. 3404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 3414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmint 3424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyThread_set_key_value(int key, void *value) 3434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 3444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm struct key *p; 3454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm assert(value != NULL); 3474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm p = find_key(key, value); 3484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (p == NULL) 3494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return -1; 3504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else 3514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return 0; 3524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 3534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Retrieve the value associated with key in the current thread, or NULL 3554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * if the current thread doesn't have an association for key. 3564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 3574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmvoid * 3584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyThread_get_key_value(int key) 3594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 3604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm struct key *p = find_key(key, NULL); 3614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (p == NULL) 3634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 3644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else 3654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return p->value; 3664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 3674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Forget the current thread's association for key, if any. */ 3694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmvoid 3704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyThread_delete_key_value(int key) 3714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 3724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm long id = PyThread_get_thread_ident(); 3734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm struct key *p, **q; 3744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyThread_acquire_lock(keymutex, 1); 3764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm q = &keyhead; 3774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm while ((p = *q) != NULL) { 3784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (p->key == key && p->id == id) { 3794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *q = p->next; 3804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm free((void *)p); 3814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* NB This does *not* free p->value! */ 3824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break; 3834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 3844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else 3854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm q = &p->next; 3864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 3874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyThread_release_lock(keymutex); 3884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 3894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 3904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Forget everything not associated with the current thread id. 3914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * This function is called from PyOS_AfterFork(). It is necessary 3924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * because other thread ids which were in use at the time of the fork 3934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * may be reused for new threads created in the forked process. 3944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 3954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmvoid 3964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyThread_ReInitTLS(void) 3974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 3984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm long id = PyThread_get_thread_ident(); 3994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm struct key *p, **q; 4004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (!keymutex) 4024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return; 4034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* As with interpreter_lock in PyEval_ReInitThreads() 4054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm we just create a new lock without freeing the old one */ 4064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm keymutex = PyThread_allocate_lock(); 4074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Delete all keys which do not match the current thread id */ 4094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm q = &keyhead; 4104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm while ((p = *q) != NULL) { 4114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if (p->id != id) { 4124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *q = p->next; 4134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm free((void *)p); 4144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* NB This does *not* free p->value! */ 4154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 4164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else 4174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm q = &p->next; 4184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 4194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 4204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 4214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif /* Py_HAVE_NATIVE_TLS */ 422