LCOV - code coverage report
Current view: top level - libreoffice/workdir/unxlngi6.pro/UnpackedTarball/python3/Python - thread.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 25 37 67.6 %
Date: 2012-12-17 Functions: 2 4 50.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10