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