view Python/thread.c @ 42309:bd6acfdb47d2

Merged revisions 56301-56442 via svnmerge from svn+ssh://pythondev@svn.python.org/python/branches/p3yk ................ r56322 | kurt.kaiser | 2007-07-12 11:35:03 -0700 (Thu, 12 Jul 2007) | 2 lines Replace obscure code which was failing in py3k. ................ r56323 | kurt.kaiser | 2007-07-12 11:44:12 -0700 (Thu, 12 Jul 2007) | 3 lines 1. Remove new division option 2. Update IDLE version to 3.0x ................ r56327 | kurt.kaiser | 2007-07-12 12:20:20 -0700 (Thu, 12 Jul 2007) | 5 lines Fix another instance of this defect in Tkinter, and one in IDLE. Patch 1724999 by Ali Gholami Rudi -- avoid complaints about dict size change during iter in destroy call. ................ r56339 | georg.brandl | 2007-07-13 03:07:25 -0700 (Fri, 13 Jul 2007) | 2 lines Fix #1753310: regrtest -x doesn't work anymore ................ r56361 | kurt.kaiser | 2007-07-13 18:25:24 -0700 (Fri, 13 Jul 2007) | 2 lines convert a map() iterator to a list to get this working. ................ r56362 | kurt.kaiser | 2007-07-13 18:53:45 -0700 (Fri, 13 Jul 2007) | 2 lines Was modifying dict during iteration. ................ r56376 | collin.winter | 2007-07-14 11:56:19 -0700 (Sat, 14 Jul 2007) | 1 line Add an example of class decorators to test_grammar. ................ r56377 | collin.winter | 2007-07-14 12:00:17 -0700 (Sat, 14 Jul 2007) | 1 line Add a basic example of dictcomps to test_grammar. ................ r56413 | neal.norwitz | 2007-07-17 00:21:18 -0700 (Tue, 17 Jul 2007) | 149 lines Merged revisions 56202-56412 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r56204 | ronald.oussoren | 2007-07-08 23:02:21 -0700 (Sun, 08 Jul 2007) | 2 lines Patch 1693258: Fix for duplicate "preferences" menu-OS X ........ r56207 | ronald.oussoren | 2007-07-09 01:41:15 -0700 (Mon, 09 Jul 2007) | 4 lines Patch 1673122: be explicit about which libtool to use, to avoid name clashes when a users install GNU libtool early in his PATH ........ r56280 | georg.brandl | 2007-07-11 12:41:49 -0700 (Wed, 11 Jul 2007) | 2 lines Fix #1752132: wrong comment in opcode description. ........ r56293 | georg.brandl | 2007-07-12 01:05:45 -0700 (Thu, 12 Jul 2007) | 3 lines Patch #1752270, #1750931: complain if urllib2 add_handler called without handler. ........ r56296 | georg.brandl | 2007-07-12 01:11:29 -0700 (Thu, 12 Jul 2007) | 2 lines Patch #1739696: use code.co_code only if really necessary ........ r56298 | georg.brandl | 2007-07-12 01:38:00 -0700 (Thu, 12 Jul 2007) | 3 lines Patch #1673759: add a missing overflow check when formatting floats with %G. ........ r56302 | georg.brandl | 2007-07-12 02:06:41 -0700 (Thu, 12 Jul 2007) | 2 lines Patch #1731659: improve time.strptime docs. ........ r56304 | georg.brandl | 2007-07-12 02:24:04 -0700 (Thu, 12 Jul 2007) | 2 lines Patch #1731169: clean up expected skips list. ........ r56306 | georg.brandl | 2007-07-12 02:37:49 -0700 (Thu, 12 Jul 2007) | 3 lines Bug #1637365: add subsection about "__name__ == __main__" to the Python tutorial. ........ r56308 | georg.brandl | 2007-07-12 02:59:22 -0700 (Thu, 12 Jul 2007) | 5 lines Patch #1675424: Added tests for uncovered code in the zipfile module. The KeyError raised by Zipfile.getinfo for nonexistent names now has a descriptive message. ........ r56340 | facundo.batista | 2007-07-13 03:43:44 -0700 (Fri, 13 Jul 2007) | 6 lines Added tests for basic behavior of DateTime, Binary, and Fault classes and the escape function. Check that marshalling recursive sequences & dicts raises TypeError. Check that marshalling out-of-range ints raises OverflowError [Alan McIntyre - GSoC] ........ r56345 | raymond.hettinger | 2007-07-13 05:09:41 -0700 (Fri, 13 Jul 2007) | 1 line Correct the docs for takewhile(). Improve the recipe for nth(). Should be backported ........ r56348 | thomas.heller | 2007-07-13 06:59:39 -0700 (Fri, 13 Jul 2007) | 4 lines Repair COMError. Since exceptions are new style classes now, setting the methods and docstring after the type creation does not work, they must be in the dictionary before creating the type. ........ r56349 | thomas.heller | 2007-07-13 07:18:06 -0700 (Fri, 13 Jul 2007) | 1 line Add tests for _ctypes.COMError. ........ r56350 | thomas.heller | 2007-07-13 09:50:43 -0700 (Fri, 13 Jul 2007) | 4 lines Do not try to load the GLUT library in the ctypes tests. This test adds little value, but has a large problem on OS X, as explained in SF# 1581906. ........ r56352 | thomas.heller | 2007-07-13 10:12:23 -0700 (Fri, 13 Jul 2007) | 3 lines Fix for SF# 1701409: segfault in c_char_p of ctypes. The repr output of c_char_p and c_wchar_p has changed as a sideeffect. ........ r56355 | thomas.heller | 2007-07-13 10:46:54 -0700 (Fri, 13 Jul 2007) | 3 lines Fix for SF# 1649098: avoid zero-sized array declaration in structure. ........ r56357 | thomas.heller | 2007-07-13 12:51:55 -0700 (Fri, 13 Jul 2007) | 3 lines PyType_stgdict() returns a borrowed reference which must not be Py_DECREF'd. ........ r56360 | barry.warsaw | 2007-07-13 15:12:58 -0700 (Fri, 13 Jul 2007) | 10 lines In response to this SF bug: [ 1752723 ] email.message_from_string: initial line gets discarded I added a test to assert that when the first line of text passed to message_from_string() contains a leading space, the message ends up with the appropriate FirstHeaderLineIsContinuationDefect on its defects list. The bug is invalid. ........ r56364 | georg.brandl | 2007-07-14 10:12:23 -0700 (Sat, 14 Jul 2007) | 2 lines Bug #1753406: missing \versionadded for subprocess.check_call. ........ r56366 | georg.brandl | 2007-07-14 10:32:41 -0700 (Sat, 14 Jul 2007) | 2 lines Clarify webbrowser.open description. ........ r56380 | andrew.kuchling | 2007-07-14 13:58:21 -0700 (Sat, 14 Jul 2007) | 1 line Typo fix ........ r56382 | andrew.kuchling | 2007-07-14 14:56:19 -0700 (Sat, 14 Jul 2007) | 7 lines Avoid exception if there's a stray directory inside a Maildir folder. The Maildir specification doesn't seem to say anything about this situation, and it can happen if you're keeping a Maildir mailbox in Subversion (.svn directories) or some similar system. The patch just ignores directories in the cur/, new/, tmp/ folders. ........ r56392 | facundo.batista | 2007-07-14 15:41:45 -0700 (Sat, 14 Jul 2007) | 6 lines First version. Includes tests for helper functions: read, write, _exception, readwrite, closeall, compact_traceback; and for classes dispatcher, dispatcher_with_send, and file_wrapper. [Alan McIntyre - GSoC] ........ r56399 | facundo.batista | 2007-07-15 13:30:39 -0700 (Sun, 15 Jul 2007) | 5 lines Changed the used port and commented out some tests that uses a non documented function that appers to uses resources not present in Windows. ........ r56412 | facundo.batista | 2007-07-16 19:19:39 -0700 (Mon, 16 Jul 2007) | 6 lines Prevent asyncore.dispatcher tests from hanging by adding loop counters to server & client, and by adding asyncore.close_all calls in tearDown. Also choose correct expected logging results based on the value of __debug__ [Alan McIntyre - GSoC] ........ ................ r56442 | guido.van.rossum | 2007-07-18 10:26:38 -0700 (Wed, 18 Jul 2007) | 14 lines Merged revisions 56413-56441 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r56439 | georg.brandl | 2007-07-17 23:37:55 -0700 (Tue, 17 Jul 2007) | 2 lines Use "Unix" as platform name, not "UNIX". ........ r56441 | guido.van.rossum | 2007-07-18 10:19:14 -0700 (Wed, 18 Jul 2007) | 3 lines SF patch# 1755885 by Kurt Kaiser: show location of Unicode escape errors. (Slightly tweaked for style and refcounts.) ........ ................
author Guido van Rossum <guido@python.org>
date Wed, 18 Jul 2007 18:15:48 +0000
parents 654c380cf8b9
children a5e984eda45a
line wrap: on
line source


/* Thread package.
   This is intended to be usable independently from Python.
   The implementation for system foobar is in a file thread_foobar.h
   which is included by this file dependent on config settings.
   Stuff shared by all thread_*.h files is collected here. */

#include "Python.h"


#ifndef _POSIX_THREADS
/* This means pthreads are not implemented in libc headers, hence the macro
   not present in unistd.h. But they still can be implemented as an external
   library (e.g. gnu pth in pthread emulation) */
# ifdef HAVE_PTHREAD_H
#  include <pthread.h> /* _POSIX_THREADS */
# endif
#endif

#ifndef DONT_HAVE_STDIO_H
#include <stdio.h>
#endif

#include <stdlib.h>

#ifdef __sgi
#ifndef HAVE_PTHREAD_H /* XXX Need to check in configure.in */
#undef _POSIX_THREADS
#endif
#endif

#include "pythread.h"

#ifndef _POSIX_THREADS

#ifdef __sgi
#define SGI_THREADS
#endif

#ifdef HAVE_THREAD_H
#define SOLARIS_THREADS
#endif

#if defined(sun) && !defined(SOLARIS_THREADS)
#define SUN_LWP
#endif

/* Check if we're running on HP-UX and _SC_THREADS is defined. If so, then
   enough of the Posix threads package is implimented to support python 
   threads.

   This is valid for HP-UX 11.23 running on an ia64 system. If needed, add
   a check of __ia64 to verify that we're running on a ia64 system instead
   of a pa-risc system.
*/
#ifdef __hpux
#ifdef _SC_THREADS
#define _POSIX_THREADS
#endif
#endif

#endif /* _POSIX_THREADS */


#ifdef Py_DEBUG
static int thread_debug = 0;
#define dprintf(args)	(void)((thread_debug & 1) && printf args)
#define d2printf(args)	((thread_debug & 8) && printf args)
#else
#define dprintf(args)
#define d2printf(args)
#endif

static int initialized;

static void PyThread__init_thread(void); /* Forward */

void
PyThread_init_thread(void)
{
#ifdef Py_DEBUG
	char *p = getenv("THREADDEBUG");

	if (p) {
		if (*p)
			thread_debug = atoi(p);
		else
			thread_debug = 1;
	}
#endif /* Py_DEBUG */
	if (initialized)
		return;
	initialized = 1;
	dprintf(("PyThread_init_thread called\n"));
	PyThread__init_thread();
}

/* Support for runtime thread stack size tuning.
   A value of 0 means using the platform's default stack size
   or the size specified by the THREAD_STACK_SIZE macro. */
static size_t _pythread_stacksize = 0;

#ifdef SGI_THREADS
#include "thread_sgi.h"
#endif

#ifdef SOLARIS_THREADS
#include "thread_solaris.h"
#endif

#ifdef SUN_LWP
#include "thread_lwp.h"
#endif

#ifdef HAVE_PTH
#include "thread_pth.h"
#undef _POSIX_THREADS
#endif

#ifdef _POSIX_THREADS
#include "thread_pthread.h"
#endif

#ifdef C_THREADS
#include "thread_cthread.h"
#endif

#ifdef NT_THREADS
#include "thread_nt.h"
#endif

#ifdef OS2_THREADS
#include "thread_os2.h"
#endif

#ifdef BEOS_THREADS
#include "thread_beos.h"
#endif

#ifdef WINCE_THREADS
#include "thread_wince.h"
#endif

#ifdef PLAN9_THREADS
#include "thread_plan9.h"
#endif

#ifdef ATHEOS_THREADS
#include "thread_atheos.h"
#endif

/*
#ifdef FOOBAR_THREADS
#include "thread_foobar.h"
#endif
*/

/* return the current thread stack size */
size_t
PyThread_get_stacksize(void)
{
	return _pythread_stacksize;
}

/* Only platforms defining a THREAD_SET_STACKSIZE() macro
   in thread_<platform>.h support changing the stack size.
   Return 0 if stack size is valid,
          -1 if stack size value is invalid,
          -2 if setting stack size is not supported. */
int
PyThread_set_stacksize(size_t size)
{
#if defined(THREAD_SET_STACKSIZE)
	return THREAD_SET_STACKSIZE(size);
#else
	return -2;
#endif
}

#ifndef Py_HAVE_NATIVE_TLS
/* If the platform has not supplied a platform specific
   TLS implementation, provide our own.

   This code stolen from "thread_sgi.h", where it was the only
   implementation of an existing Python TLS API.
*/
/* ------------------------------------------------------------------------
Per-thread data ("key") support.

Use PyThread_create_key() to create a new key.  This is typically shared
across threads.

Use PyThread_set_key_value(thekey, value) to associate void* value with
thekey in the current thread.  Each thread has a distinct mapping of thekey
to a void* value.  Caution:  if the current thread already has a mapping
for thekey, value is ignored.

Use PyThread_get_key_value(thekey) to retrieve the void* value associated
with thekey in the current thread.  This returns NULL if no value is
associated with thekey in the current thread.

Use PyThread_delete_key_value(thekey) to forget the current thread's associated
value for thekey.  PyThread_delete_key(thekey) forgets the values associated
with thekey across *all* threads.

While some of these functions have error-return values, none set any
Python exception.

None of the functions does memory management on behalf of the void* values.
You need to allocate and deallocate them yourself.  If the void* values
happen to be PyObject*, these functions don't do refcount operations on
them either.

The GIL does not need to be held when calling these functions; they supply
their own locking.  This isn't true of PyThread_create_key(), though (see
next paragraph).

There's a hidden assumption that PyThread_create_key() will be called before
any of the other functions are called.  There's also a hidden assumption
that calls to PyThread_create_key() are serialized externally.
------------------------------------------------------------------------ */

/* A singly-linked list of struct key objects remembers all the key->value
 * associations.  File static keyhead heads the list.  keymutex is used
 * to enforce exclusion internally.
 */
struct key {
	/* Next record in the list, or NULL if this is the last record. */
	struct key *next;

	/* The thread id, according to PyThread_get_thread_ident(). */
	long id;

	/* The key and its associated value. */
	int key;
	void *value;
};

static struct key *keyhead = NULL;
static PyThread_type_lock keymutex = NULL;
static int nkeys = 0;  /* PyThread_create_key() hands out nkeys+1 next */

/* Internal helper.
 * If the current thread has a mapping for key, the appropriate struct key*
 * is returned.  NB:  value is ignored in this case!
 * If there is no mapping for key in the current thread, then:
 *     If value is NULL, NULL is returned.
 *     Else a mapping of key to value is created for the current thread,
 *     and a pointer to a new struct key* is returned; except that if
 *     malloc() can't find room for a new struct key*, NULL is returned.
 * So when value==NULL, this acts like a pure lookup routine, and when
 * value!=NULL, this acts like dict.setdefault(), returning an existing
 * mapping if one exists, else creating a new mapping.
 *
 * Caution:  this used to be too clever, trying to hold keymutex only
 * around the "p->next = keyhead; keyhead = p" pair.  That allowed
 * another thread to mutate the list, via key deletion, concurrent with
 * find_key() crawling over the list.  Hilarity ensued.  For example, when
 * the for-loop here does "p = p->next", p could end up pointing at a
 * record that PyThread_delete_key_value() was concurrently free()'ing.
 * That could lead to anything, from failing to find a key that exists, to
 * segfaults.  Now we lock the whole routine.
 */
static struct key *
find_key(int key, void *value)
{
	struct key *p;
	long id = PyThread_get_thread_ident();

	if (!keymutex)
		return NULL;
	PyThread_acquire_lock(keymutex, 1);
	for (p = keyhead; p != NULL; p = p->next) {
		if (p->id == id && p->key == key)
			goto Done;
	}
	if (value == NULL) {
		assert(p == NULL);
		goto Done;
	}
	p = (struct key *)malloc(sizeof(struct key));
	if (p != NULL) {
		p->id = id;
		p->key = key;
		p->value = value;
		p->next = keyhead;
		keyhead = p;
	}
 Done:
	PyThread_release_lock(keymutex);
	return p;
}

/* Return a new key.  This must be called before any other functions in
 * this family, and callers must arrange to serialize calls to this
 * function.  No violations are detected.
 */
int
PyThread_create_key(void)
{
	/* All parts of this function are wrong if it's called by multiple
	 * threads simultaneously.
	 */
	if (keymutex == NULL)
		keymutex = PyThread_allocate_lock();
	return ++nkeys;
}

/* Forget the associations for key across *all* threads. */
void
PyThread_delete_key(int key)
{
	struct key *p, **q;

	PyThread_acquire_lock(keymutex, 1);
	q = &keyhead;
	while ((p = *q) != NULL) {
		if (p->key == key) {
			*q = p->next;
			free((void *)p);
			/* NB This does *not* free p->value! */
		}
		else
			q = &p->next;
	}
	PyThread_release_lock(keymutex);
}

/* Confusing:  If the current thread has an association for key,
 * value is ignored, and 0 is returned.  Else an attempt is made to create
 * an association of key to value for the current thread.  0 is returned
 * if that succeeds, but -1 is returned if there's not enough memory
 * to create the association.  value must not be NULL.
 */
int
PyThread_set_key_value(int key, void *value)
{
	struct key *p;

	assert(value != NULL);
	p = find_key(key, value);
	if (p == NULL)
		return -1;
	else
		return 0;
}

/* Retrieve the value associated with key in the current thread, or NULL
 * if the current thread doesn't have an association for key.
 */
void *
PyThread_get_key_value(int key)
{
	struct key *p = find_key(key, NULL);

	if (p == NULL)
		return NULL;
	else
		return p->value;
}

/* Forget the current thread's association for key, if any. */
void
PyThread_delete_key_value(int key)
{
	long id = PyThread_get_thread_ident();
	struct key *p, **q;

	PyThread_acquire_lock(keymutex, 1);
	q = &keyhead;
	while ((p = *q) != NULL) {
		if (p->key == key && p->id == id) {
			*q = p->next;
			free((void *)p);
			/* NB This does *not* free p->value! */
			break;
		}
		else
			q = &p->next;
	}
	PyThread_release_lock(keymutex);
}

#endif /* Py_HAVE_NATIVE_TLS */