pystate.c 14.4 KB
Newer Older
1 2 3 4 5

/* Thread and interpreter state structures and their interfaces */

#include "Python.h"

6 7 8 9 10 11 12 13 14 15
/* --------------------------------------------------------------------------
CAUTION

Always use malloc() and free() directly in this file.  A number of these
functions are advertised as safe to call when the GIL isn't held, and in
a debug build Python redirects (e.g.) PyMem_NEW (etc) to Python's debugging
obmalloc functions.  Those aren't thread-safe (they rely on the GIL to avoid
the expense of doing their own locking).
-------------------------------------------------------------------------- */

16 17 18 19 20 21 22 23 24 25
#ifdef HAVE_DLOPEN
#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
#endif
#ifndef RTLD_LAZY
#define RTLD_LAZY 1
#endif
#endif


26 27 28 29 30 31 32
#define ZAP(x) { \
	PyObject *tmp = (PyObject *)(x); \
	(x) = NULL; \
	Py_XDECREF(tmp); \
}


Guido van Rossum's avatar
Guido van Rossum committed
33 34 35
#ifdef WITH_THREAD
#include "pythread.h"
static PyThread_type_lock head_mutex = NULL; /* Protects interp->tstate_head */
36
#define HEAD_INIT() (void)(head_mutex || (head_mutex = PyThread_allocate_lock()))
Guido van Rossum's avatar
Guido van Rossum committed
37 38
#define HEAD_LOCK() PyThread_acquire_lock(head_mutex, WAIT_LOCK)
#define HEAD_UNLOCK() PyThread_release_lock(head_mutex)
Michael W. Hudson's avatar
Michael W. Hudson committed
39 40 41 42 43 44

/* The single PyInterpreterState used by this process'
   GILState implementation
*/
static PyInterpreterState *autoInterpreterState = NULL;
static int autoTLSkey = 0;
Guido van Rossum's avatar
Guido van Rossum committed
45 46 47 48 49 50
#else
#define HEAD_INIT() /* Nothing */
#define HEAD_LOCK() /* Nothing */
#define HEAD_UNLOCK() /* Nothing */
#endif

51
static PyInterpreterState *interp_head = NULL;
52

53
PyThreadState *_PyThreadState_Current = NULL;
54
PyThreadFrameGetter _PyThreadState_GetFrame = NULL;
55

Michael W. Hudson's avatar
Michael W. Hudson committed
56
#ifdef WITH_THREAD
Michael W. Hudson's avatar
Michael W. Hudson committed
57
static void _PyGILState_NoteThreadState(PyThreadState* tstate);
Michael W. Hudson's avatar
Michael W. Hudson committed
58
#endif
Michael W. Hudson's avatar
Michael W. Hudson committed
59

60 61

PyInterpreterState *
62
PyInterpreterState_New(void)
63
{
64 65
	PyInterpreterState *interp = (PyInterpreterState *)
				     malloc(sizeof(PyInterpreterState));
66

67
	if (interp != NULL) {
Guido van Rossum's avatar
Guido van Rossum committed
68
		HEAD_INIT();
69
		interp->modules = NULL;
70
		interp->sysdict = NULL;
71 72
		interp->builtins = NULL;
		interp->tstate_head = NULL;
73 74 75
		interp->codec_search_path = NULL;
		interp->codec_search_cache = NULL;
		interp->codec_error_registry = NULL;
76 77 78 79 80 81
#ifdef HAVE_DLOPEN
#ifdef RTLD_NOW
                interp->dlopenflags = RTLD_NOW;
#else
		interp->dlopenflags = RTLD_LAZY;
#endif
82 83 84
#endif
#ifdef WITH_TSC
		interp->tscdump = 0;
85
#endif
86

87
		HEAD_LOCK();
88 89
		interp->next = interp_head;
		interp_head = interp;
90
		HEAD_UNLOCK();
91
	}
92

93 94 95 96 97
	return interp;
}


void
98
PyInterpreterState_Clear(PyInterpreterState *interp)
99 100
{
	PyThreadState *p;
Guido van Rossum's avatar
Guido van Rossum committed
101
	HEAD_LOCK();
102 103
	for (p = interp->tstate_head; p != NULL; p = p->next)
		PyThreadState_Clear(p);
Guido van Rossum's avatar
Guido van Rossum committed
104
	HEAD_UNLOCK();
105 106 107
	ZAP(interp->codec_search_path);
	ZAP(interp->codec_search_cache);
	ZAP(interp->codec_error_registry);
108 109 110 111 112 113 114
	ZAP(interp->modules);
	ZAP(interp->sysdict);
	ZAP(interp->builtins);
}


static void
115
zapthreads(PyInterpreterState *interp)
116
{
Guido van Rossum's avatar
Guido van Rossum committed
117 118 119 120
	PyThreadState *p;
	/* No need to lock the mutex here because this should only happen
	   when the threads are all really dead (XXX famous last words). */
	while ((p = interp->tstate_head) != NULL) {
121 122 123
		PyThreadState_Delete(p);
	}
}
124

125 126

void
127
PyInterpreterState_Delete(PyInterpreterState *interp)
128 129 130
{
	PyInterpreterState **p;
	zapthreads(interp);
131
	HEAD_LOCK();
132 133 134 135 136 137 138 139 140 141
	for (p = &interp_head; ; p = &(*p)->next) {
		if (*p == NULL)
			Py_FatalError(
				"PyInterpreterState_Delete: invalid interp");
		if (*p == interp)
			break;
	}
	if (interp->tstate_head != NULL)
		Py_FatalError("PyInterpreterState_Delete: remaining threads");
	*p = interp->next;
142
	HEAD_UNLOCK();
143
	free(interp);
144 145 146
}


147 148 149 150 151 152 153
/* Default implementation for _PyThreadState_GetFrame */
static struct _frame *
threadstate_getframe(PyThreadState *self)
{
	return self->frame;
}

154
PyThreadState *
155
PyThreadState_New(PyInterpreterState *interp)
156
{
157 158
	PyThreadState *tstate = (PyThreadState *)malloc(sizeof(PyThreadState));

159
	if (_PyThreadState_GetFrame == NULL)
160
		_PyThreadState_GetFrame = threadstate_getframe;
161

162
	if (tstate != NULL) {
163
		tstate->interp = interp;
164 165 166 167

		tstate->frame = NULL;
		tstate->recursion_depth = 0;
		tstate->tracing = 0;
168
		tstate->use_tracing = 0;
169
		tstate->tick_counter = 0;
170
		tstate->gilstate_counter = 0;
171
		tstate->async_exc = NULL;
172
#ifdef WITH_THREAD
173
		tstate->thread_id = PyThread_get_thread_ident();
174 175 176
#else
		tstate->thread_id = 0;
#endif
177

178 179
		tstate->dict = NULL;

180 181 182 183 184 185 186 187
		tstate->curexc_type = NULL;
		tstate->curexc_value = NULL;
		tstate->curexc_traceback = NULL;

		tstate->exc_type = NULL;
		tstate->exc_value = NULL;
		tstate->exc_traceback = NULL;

188 189 190 191
		tstate->c_profilefunc = NULL;
		tstate->c_tracefunc = NULL;
		tstate->c_profileobj = NULL;
		tstate->c_traceobj = NULL;
192

Michael W. Hudson's avatar
Michael W. Hudson committed
193
#ifdef WITH_THREAD
Michael W. Hudson's avatar
Michael W. Hudson committed
194
		_PyGILState_NoteThreadState(tstate);
Michael W. Hudson's avatar
Michael W. Hudson committed
195
#endif
Michael W. Hudson's avatar
Michael W. Hudson committed
196

Guido van Rossum's avatar
Guido van Rossum committed
197
		HEAD_LOCK();
198 199
		tstate->next = interp->tstate_head;
		interp->tstate_head = tstate;
Guido van Rossum's avatar
Guido van Rossum committed
200
		HEAD_UNLOCK();
201
	}
202

203 204 205 206 207
	return tstate;
}


void
208
PyThreadState_Clear(PyThreadState *tstate)
209
{
210
	if (Py_VerboseFlag && tstate->frame != NULL)
211
		fprintf(stderr,
212
		  "PyThreadState_Clear: warning: thread still has a frame\n");
213 214

	ZAP(tstate->frame);
215

216
	ZAP(tstate->dict);
217
	ZAP(tstate->async_exc);
218

219 220 221
	ZAP(tstate->curexc_type);
	ZAP(tstate->curexc_value);
	ZAP(tstate->curexc_traceback);
222

223 224 225
	ZAP(tstate->exc_type);
	ZAP(tstate->exc_value);
	ZAP(tstate->exc_traceback);
226

227 228 229 230
	tstate->c_profilefunc = NULL;
	tstate->c_tracefunc = NULL;
	ZAP(tstate->c_profileobj);
	ZAP(tstate->c_traceobj);
231
}
232 233


234 235 236
/* Common code for PyThreadState_Delete() and PyThreadState_DeleteCurrent() */
static void
tstate_delete_common(PyThreadState *tstate)
237 238 239 240 241 242 243 244
{
	PyInterpreterState *interp;
	PyThreadState **p;
	if (tstate == NULL)
		Py_FatalError("PyThreadState_Delete: NULL tstate");
	interp = tstate->interp;
	if (interp == NULL)
		Py_FatalError("PyThreadState_Delete: NULL interp");
Guido van Rossum's avatar
Guido van Rossum committed
245
	HEAD_LOCK();
246 247 248 249 250 251 252 253
	for (p = &interp->tstate_head; ; p = &(*p)->next) {
		if (*p == NULL)
			Py_FatalError(
				"PyThreadState_Delete: invalid tstate");
		if (*p == tstate)
			break;
	}
	*p = tstate->next;
Guido van Rossum's avatar
Guido van Rossum committed
254
	HEAD_UNLOCK();
255
	free(tstate);
256 257 258
}


259 260 261 262 263 264
void
PyThreadState_Delete(PyThreadState *tstate)
{
	if (tstate == _PyThreadState_Current)
		Py_FatalError("PyThreadState_Delete: tstate is still current");
	tstate_delete_common(tstate);
265 266 267 268
#ifdef WITH_THREAD
	if (autoTLSkey && PyThread_get_key_value(autoTLSkey) == tstate)
		PyThread_delete_key_value(autoTLSkey);
#endif /* WITH_THREAD */
269 270 271 272 273 274 275 276 277 278 279 280 281
}


#ifdef WITH_THREAD
void
PyThreadState_DeleteCurrent()
{
	PyThreadState *tstate = _PyThreadState_Current;
	if (tstate == NULL)
		Py_FatalError(
			"PyThreadState_DeleteCurrent: no current tstate");
	_PyThreadState_Current = NULL;
	tstate_delete_common(tstate);
Michael W. Hudson's avatar
Michael W. Hudson committed
282 283
	if (autoTLSkey && PyThread_get_key_value(autoTLSkey) == tstate)
		PyThread_delete_key_value(autoTLSkey);
284 285 286 287 288
	PyEval_ReleaseLock();
}
#endif /* WITH_THREAD */


289
PyThreadState *
290
PyThreadState_Get(void)
291
{
292
	if (_PyThreadState_Current == NULL)
293 294
		Py_FatalError("PyThreadState_Get: no current thread");

295
	return _PyThreadState_Current;
296 297 298 299
}


PyThreadState *
300
PyThreadState_Swap(PyThreadState *new)
301
{
302
	PyThreadState *old = _PyThreadState_Current;
303

304
	_PyThreadState_Current = new;
305
	/* It should not be possible for more than one thread state
Tim Peters's avatar
Tim Peters committed
306
	   to be used for a thread.  Check this the best we can in debug
307 308
	   builds.
	*/
309
#if defined(Py_DEBUG) && defined(WITH_THREAD)
310 311
	if (new) {
		PyThreadState *check = PyGILState_GetThisThreadState();
312
		if (check && check->interp == new->interp && check != new)
313 314 315
			Py_FatalError("Invalid thread state for this thread");
	}
#endif
316 317
	return old;
}
318 319 320 321

/* An extension mechanism to store arbitrary additional per-thread state.
   PyThreadState_GetDict() returns a dictionary that can be used to hold such
   state; the caller should pick a unique key and store its state there.  If
322 323
   PyThreadState_GetDict() returns NULL, an exception has *not* been raised
   and the caller should assume no per-thread state is available. */
324 325

PyObject *
326
PyThreadState_GetDict(void)
327
{
328
	if (_PyThreadState_Current == NULL)
329
		return NULL;
330

331 332 333 334 335 336
	if (_PyThreadState_Current->dict == NULL) {
		PyObject *d;
		_PyThreadState_Current->dict = d = PyDict_New();
		if (d == NULL)
			PyErr_Clear();
	}
337
	return _PyThreadState_Current->dict;
338
}
339 340


341 342
/* Asynchronously raise an exception in a thread.
   Requested by Just van Rossum and Alex Martelli.
343
   To prevent naive misuse, you must write your own extension
344 345 346 347 348 349 350
   to call this.  Must be called with the GIL held.
   Returns the number of tstates modified; if it returns a number
   greater than one, you're in trouble, and you should call it again
   with exc=NULL to revert the effect.  This raises no exceptions. */

int
PyThreadState_SetAsyncExc(long id, PyObject *exc) {
351
	PyThreadState *tstate = PyThreadState_GET();
352 353 354
	PyInterpreterState *interp = tstate->interp;
	PyThreadState *p;
	int count = 0;
355
	HEAD_LOCK();
356 357 358 359 360 361 362 363
	for (p = interp->tstate_head; p != NULL; p = p->next) {
		if (p->thread_id != id)
			continue;
		ZAP(p->async_exc);
		Py_XINCREF(exc);
		p->async_exc = exc;
		count += 1;
	}
364
	HEAD_UNLOCK();
365 366 367 368
	return count;
}


369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391
/* Routines for advanced debuggers, requested by David Beazley.
   Don't use unless you know what you are doing! */

PyInterpreterState *
PyInterpreterState_Head(void)
{
	return interp_head;
}

PyInterpreterState *
PyInterpreterState_Next(PyInterpreterState *interp) {
	return interp->next;
}

PyThreadState *
PyInterpreterState_ThreadHead(PyInterpreterState *interp) {
	return interp->tstate_head;
}

PyThreadState *
PyThreadState_Next(PyThreadState *tstate) {
	return tstate->next;
}
392

393

394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415
/* Python "auto thread state" API. */
#ifdef WITH_THREAD

/* Keep this as a static, as it is not reliable!  It can only
   ever be compared to the state for the *current* thread.
   * If not equal, then it doesn't matter that the actual
     value may change immediately after comparison, as it can't
     possibly change to the current thread's state.
   * If equal, then the current thread holds the lock, so the value can't
     change until we yield the lock.
*/
static int
PyThreadState_IsCurrent(PyThreadState *tstate)
{
	/* Must be the tstate for this thread */
	assert(PyGILState_GetThisThreadState()==tstate);
	/* On Windows at least, simple reads and writes to 32 bit values
	   are atomic.
	*/
	return tstate == _PyThreadState_Current;
}

Tim Peters's avatar
Tim Peters committed
416 417
/* Internal initialization/finalization functions called by
   Py_Initialize/Py_Finalize
418
*/
419 420
void
_PyGILState_Init(PyInterpreterState *i, PyThreadState *t)
421
{
422
	assert(i && t); /* must init with valid states */
423 424
	autoTLSkey = PyThread_create_key();
	autoInterpreterState = i;
425
	assert(PyThread_get_key_value(autoTLSkey) == NULL);
Michael W. Hudson's avatar
Michael W. Hudson committed
426 427 428
	assert(t->gilstate_counter == 0);

	_PyGILState_NoteThreadState(t);
429 430
}

431 432
void
_PyGILState_Fini(void)
433 434 435 436 437 438
{
	PyThread_delete_key(autoTLSkey);
	autoTLSkey = 0;
	autoInterpreterState = NULL;;
}

Michael W. Hudson's avatar
Michael W. Hudson committed
439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473
/* When a thread state is created for a thread by some mechanism other than
   PyGILState_Ensure, it's important that the GILState machinery knows about
   it so it doesn't try to create another thread state for the thread (this is
   a better fix for SF bug #1010677 than the first one attempted).
*/
void
_PyGILState_NoteThreadState(PyThreadState* tstate)
{
	/* If autoTLSkey is 0, this must be the very first threadstate created
	   in Py_Initialize().  Don't do anything for now (we'll be back here
	   when _PyGILState_Init is called). */
	if (!autoTLSkey) 
		return;
	
	/* Stick the thread state for this thread in thread local storage.

	   The only situation where you can legitimately have more than one
	   thread state for an OS level thread is when there are multiple
	   interpreters, when:
	       
	       a) You shouldn't really be using the PyGILState_ APIs anyway,
	          and:

	       b) The slightly odd way PyThread_set_key_value works (see
	          comments by its implementation) means that the first thread
	          state created for that given OS level thread will "win",
	          which seems reasonable behaviour.
	*/
	if (PyThread_set_key_value(autoTLSkey, (void *)tstate) < 0)
		Py_FatalError("Couldn't create autoTLSkey mapping");

	/* PyGILState_Release must not try to delete this thread state. */
	tstate->gilstate_counter = 1;
}

474
/* The public functions */
475 476
PyThreadState *
PyGILState_GetThisThreadState(void)
477
{
478
	if (autoInterpreterState == NULL || autoTLSkey == 0)
479
		return NULL;
480
	return (PyThreadState *)PyThread_get_key_value(autoTLSkey);
481 482
}

483 484
PyGILState_STATE
PyGILState_Ensure(void)
485 486 487
{
	int current;
	PyThreadState *tcur;
Tim Peters's avatar
Tim Peters committed
488 489
	/* Note that we do not auto-init Python here - apart from
	   potential races with 2 threads auto-initializing, pep-311
490 491 492 493 494
	   spells out other issues.  Embedders are expected to have
	   called Py_Initialize() and usually PyEval_InitThreads().
	*/
	assert(autoInterpreterState); /* Py_Initialize() hasn't been called! */
	tcur = PyThread_get_key_value(autoTLSkey);
495
	if (tcur == NULL) {
496 497
		/* Create a new thread state for this thread */
		tcur = PyThreadState_New(autoInterpreterState);
498
		if (tcur == NULL)
499
			Py_FatalError("Couldn't create thread-state for new thread");
Michael W. Hudson's avatar
Michael W. Hudson committed
500 501 502
		/* This is our thread state!  We'll need to delete it in the
		   matching call to PyGILState_Release(). */
		tcur->gilstate_counter = 0;
503
		current = 0; /* new thread state is never current */
504 505
	}
	else
506
		current = PyThreadState_IsCurrent(tcur);
507
	if (current == 0)
508 509 510
		PyEval_RestoreThread(tcur);
	/* Update our counter in the thread-state - no need for locks:
	   - tcur will remain valid as we hold the GIL.
Tim Peters's avatar
Tim Peters committed
511
	   - the counter is safe as we are the only thread "allowed"
512 513
	     to modify this value
	*/
514
	++tcur->gilstate_counter;
515 516 517
	return current ? PyGILState_LOCKED : PyGILState_UNLOCKED;
}

518 519
void
PyGILState_Release(PyGILState_STATE oldstate)
520 521
{
	PyThreadState *tcur = PyThread_get_key_value(autoTLSkey);
522
	if (tcur == NULL)
523 524 525 526
		Py_FatalError("auto-releasing thread-state, "
		              "but no thread-state for this thread");
	/* We must hold the GIL and have our thread state current */
	/* XXX - remove the check - the assert should be fine,
Tim Peters's avatar
Tim Peters committed
527
	   but while this is very new (April 2003), the extra check
528 529
	   by release-only users can't hurt.
	*/
530
	if (! PyThreadState_IsCurrent(tcur))
531
		Py_FatalError("This thread state must be current when releasing");
532 533 534
	assert(PyThreadState_IsCurrent(tcur));
	--tcur->gilstate_counter;
	assert(tcur->gilstate_counter >= 0); /* illegal counter value */
535

536 537 538
	/* If we're going to destroy this thread-state, we must
	 * clear it while the GIL is held, as destructors may run.
	 */
539
	if (tcur->gilstate_counter == 0) {
540
		/* can't have been locked when we created it */
541
		assert(oldstate == PyGILState_UNLOCKED);
542
		PyThreadState_Clear(tcur);
543 544 545 546 547 548
		/* Delete the thread-state.  Note this releases the GIL too!
		 * It's vital that the GIL be held here, to avoid shutdown
		 * races; see bugs 225673 and 1061968 (that nasty bug has a
		 * habit of coming back).
		 */
		PyThreadState_DeleteCurrent();
549 550
	}
	/* Release the lock if necessary */
551
	else if (oldstate == PyGILState_UNLOCKED)
Michael W. Hudson's avatar
Michael W. Hudson committed
552
		PyEval_SaveThread();
553 554
}
#endif /* WITH_THREAD */