_threadmodule.c 18.6 KB
Newer Older
1 2 3 4

/* Thread module */
/* Interface to Sjoerd's portable C thread library */

Barry Warsaw's avatar
Barry Warsaw committed
5
#include "Python.h"
6

7
#ifndef WITH_THREAD
8
#error "Error!  The rest of Python is not compiled with thread support."
9
#error "Rerun configure, adding a --with-threads option."
10
#error "Then run `make clean' followed by `make'."
11 12
#endif

13
#include "pythread.h"
14

Barry Warsaw's avatar
Barry Warsaw committed
15
static PyObject *ThreadError;
16 17 18 19 20


/* Lock objects */

typedef struct {
Barry Warsaw's avatar
Barry Warsaw committed
21
	PyObject_HEAD
22
	PyThread_type_lock lock_lock;
23 24 25
} lockobject;

static void
Peter Schneider-Kamp's avatar
Peter Schneider-Kamp committed
26
lock_dealloc(lockobject *self)
27
{
28
	assert(self->lock_lock);
29
	/* Unlock the lock so it's safe to free it */
30 31
	PyThread_acquire_lock(self->lock_lock, 0);
	PyThread_release_lock(self->lock_lock);
32
	
33
	PyThread_free_lock(self->lock_lock);
34
	PyObject_Del(self);
35 36
}

Barry Warsaw's avatar
Barry Warsaw committed
37
static PyObject *
Peter Schneider-Kamp's avatar
Peter Schneider-Kamp committed
38
lock_PyThread_acquire_lock(lockobject *self, PyObject *args)
39
{
Neal Norwitz's avatar
Neal Norwitz committed
40
	int i = 1;
41

Neal Norwitz's avatar
Neal Norwitz committed
42 43
	if (!PyArg_ParseTuple(args, "|i:acquire", &i))
		return NULL;
44

Barry Warsaw's avatar
Barry Warsaw committed
45
	Py_BEGIN_ALLOW_THREADS
46
	i = PyThread_acquire_lock(self->lock_lock, i);
Barry Warsaw's avatar
Barry Warsaw committed
47
	Py_END_ALLOW_THREADS
48

49
	return PyBool_FromLong((long)i);
50 51
}

52
PyDoc_STRVAR(acquire_doc,
53
"acquire([wait]) -> None or bool\n\
54
(acquire_lock() is an obsolete synonym)\n\
55 56 57
\n\
Lock the lock.  Without argument, this blocks if the lock is already\n\
locked (even by the same thread), waiting for another thread to release\n\
58 59
the lock, and return None once the lock is acquired.\n\
With an argument, this will only block if the argument is true,\n\
60
and the return value reflects whether the lock is acquired.\n\
61
The blocking operation is not interruptible.");
62

Barry Warsaw's avatar
Barry Warsaw committed
63
static PyObject *
64
lock_PyThread_release_lock(lockobject *self)
65 66
{
	/* Sanity check: the lock must be locked */
67 68
	if (PyThread_acquire_lock(self->lock_lock, 0)) {
		PyThread_release_lock(self->lock_lock);
Barry Warsaw's avatar
Barry Warsaw committed
69
		PyErr_SetString(ThreadError, "release unlocked lock");
70 71 72
		return NULL;
	}

73
	PyThread_release_lock(self->lock_lock);
Barry Warsaw's avatar
Barry Warsaw committed
74 75
	Py_INCREF(Py_None);
	return Py_None;
76 77
}

78
PyDoc_STRVAR(release_doc,
79
"release()\n\
80
(release_lock() is an obsolete synonym)\n\
81 82 83
\n\
Release the lock, allowing another thread that is blocked waiting for\n\
the lock to acquire the lock.  The lock must be in the locked state,\n\
84
but it needn't be locked by the same thread that unlocks it.");
85

Barry Warsaw's avatar
Barry Warsaw committed
86
static PyObject *
87
lock_locked_lock(lockobject *self)
88
{
89 90
	if (PyThread_acquire_lock(self->lock_lock, 0)) {
		PyThread_release_lock(self->lock_lock);
91
		return PyBool_FromLong(0L);
92
	}
93
	return PyBool_FromLong(1L);
94 95
}

96
PyDoc_STRVAR(locked_doc,
97
"locked() -> bool\n\
98 99
(locked_lock() is an obsolete synonym)\n\
\n\
100
Return whether the lock is in the locked state.");
101

Barry Warsaw's avatar
Barry Warsaw committed
102
static PyMethodDef lock_methods[] = {
103
	{"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock, 
Neal Norwitz's avatar
Neal Norwitz committed
104
	 METH_VARARGS, acquire_doc},
105
	{"acquire",      (PyCFunction)lock_PyThread_acquire_lock, 
Neal Norwitz's avatar
Neal Norwitz committed
106
	 METH_VARARGS, acquire_doc},
107
	{"release_lock", (PyCFunction)lock_PyThread_release_lock, 
108
	 METH_NOARGS, release_doc},
109
	{"release",      (PyCFunction)lock_PyThread_release_lock, 
110
	 METH_NOARGS, release_doc},
111
	{"locked_lock",  (PyCFunction)lock_locked_lock,  
112
	 METH_NOARGS, locked_doc},
113
	{"locked",       (PyCFunction)lock_locked_lock,  
114
	 METH_NOARGS, locked_doc},
115 116
	{"__enter__",    (PyCFunction)lock_PyThread_acquire_lock,
	 METH_VARARGS, acquire_doc},
117 118
	{"__exit__",    (PyCFunction)lock_PyThread_release_lock,
	 METH_VARARGS, release_doc},
119
	{NULL,           NULL}		/* sentinel */
120 121
};

Barry Warsaw's avatar
Barry Warsaw committed
122
static PyObject *
Peter Schneider-Kamp's avatar
Peter Schneider-Kamp committed
123
lock_getattr(lockobject *self, char *name)
124
{
Barry Warsaw's avatar
Barry Warsaw committed
125
	return Py_FindMethod(lock_methods, (PyObject *)self, name);
126 127
}

Barry Warsaw's avatar
Barry Warsaw committed
128
static PyTypeObject Locktype = {
129
	PyVarObject_HEAD_INIT(&PyType_Type, 0)
130
	"_thread.lock",			/*tp_name*/
131 132
	sizeof(lockobject),		/*tp_size*/
	0,				/*tp_itemsize*/
133
	/* methods */
134 135 136 137 138 139
	(destructor)lock_dealloc,	/*tp_dealloc*/
	0,				/*tp_print*/
	(getattrfunc)lock_getattr,	/*tp_getattr*/
	0,				/*tp_setattr*/
	0,				/*tp_compare*/
	0,				/*tp_repr*/
140 141
};

142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
static lockobject *
newlockobject(void)
{
	lockobject *self;
	self = PyObject_New(lockobject, &Locktype);
	if (self == NULL)
		return NULL;
	self->lock_lock = PyThread_allocate_lock();
	if (self->lock_lock == NULL) {
		PyObject_Del(self);
		self = NULL;
		PyErr_SetString(ThreadError, "can't allocate lock");
	}
	return self;
}

158 159 160 161 162
/* Thread-local objects */

#include "structmember.h"

typedef struct {
163 164 165 166 167
	PyObject_HEAD
	PyObject *key;
	PyObject *args;
	PyObject *kw;
	PyObject *dict;
168 169 170 171 172
} localobject;

static PyObject *
local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
{
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
	localobject *self;
	PyObject *tdict;

	if (type->tp_init == PyBaseObject_Type.tp_init
	    && ((args && PyObject_IsTrue(args))
		|| (kw && PyObject_IsTrue(kw)))) {
		PyErr_SetString(PyExc_TypeError,
			  "Initialization arguments are not supported");
		return NULL;
	}

	self = (localobject *)type->tp_alloc(type, 0);
	if (self == NULL)
		return NULL;

	Py_XINCREF(args);
	self->args = args;
	Py_XINCREF(kw);
	self->kw = kw;
	self->dict = NULL;	/* making sure */
193
	self->key = PyUnicode_FromFormat("thread.local.%p", self);
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
	if (self->key == NULL) 
		goto err;

	self->dict = PyDict_New();
	if (self->dict == NULL)
		goto err;

	tdict = PyThreadState_GetDict();
	if (tdict == NULL) {
		PyErr_SetString(PyExc_SystemError,
				"Couldn't get thread-state dictionary");
		goto err;
	}

	if (PyDict_SetItem(tdict, self->key, self->dict) < 0)
		goto err;

	return (PyObject *)self;

  err:
	Py_DECREF(self);
	return NULL;
216 217 218 219 220
}

static int
local_traverse(localobject *self, visitproc visit, void *arg)
{
221 222 223
	Py_VISIT(self->args);
	Py_VISIT(self->kw);
	Py_VISIT(self->dict);
224 225 226 227 228 229
	return 0;
}

static int
local_clear(localobject *self)
{
230 231 232 233 234
	Py_CLEAR(self->key);
	Py_CLEAR(self->args);
	Py_CLEAR(self->kw);
	Py_CLEAR(self->dict);
	return 0;
235 236 237 238 239
}

static void
local_dealloc(localobject *self)
{
240 241 242 243 244 245 246 247 248 249 250 251 252
	PyThreadState *tstate;
	if (self->key
	    && (tstate = PyThreadState_Get())
	    && tstate->interp) {
		for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
		    tstate;
		    tstate = PyThreadState_Next(tstate)) 
			if (tstate->dict &&
			    PyDict_GetItem(tstate->dict, self->key))
				PyDict_DelItem(tstate->dict, self->key);
	}

	local_clear(self);
253
	Py_TYPE(self)->tp_free((PyObject*)self);
254 255 256 257 258 259 260 261
}

static PyObject *
_ldict(localobject *self)
{
	PyObject *tdict, *ldict;

	tdict = PyThreadState_GetDict();
262 263 264 265 266 267 268 269 270 271 272 273 274 275
	if (tdict == NULL) {
		PyErr_SetString(PyExc_SystemError,
				"Couldn't get thread-state dictionary");
		return NULL;
	}

	ldict = PyDict_GetItem(tdict, self->key);
	if (ldict == NULL) {
		ldict = PyDict_New(); /* we own ldict */

		if (ldict == NULL)
			return NULL;
		else {
			int i = PyDict_SetItem(tdict, self->key, ldict);
Georg Brandl's avatar
Georg Brandl committed
276
			Py_DECREF(ldict); /* now ldict is borrowed */
277 278 279 280 281 282 283 284
			if (i < 0) 
				return NULL;
		}

		Py_CLEAR(self->dict);
		Py_INCREF(ldict);
		self->dict = ldict; /* still borrowed */

285 286
		if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
		    Py_TYPE(self)->tp_init((PyObject*)self, 
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302
					   self->args, self->kw) < 0) {
			/* we need to get rid of ldict from thread so
			   we create a new one the next time we do an attr
			   acces */
			PyDict_DelItem(tdict, self->key);
			return NULL;
		}
		
	}
	else if (self->dict != ldict) {
		Py_CLEAR(self->dict);
		Py_INCREF(ldict);
		self->dict = ldict;
	}

	return ldict;
303 304 305 306 307 308
}

static int
local_setattro(localobject *self, PyObject *name, PyObject *v)
{
	PyObject *ldict;
309 310 311 312
	
	ldict = _ldict(self);
	if (ldict == NULL) 
		return -1;
313

314
	return PyObject_GenericSetAttr((PyObject *)self, name, v);
315 316 317 318 319
}

static PyObject *
local_getdict(localobject *self, void *closure)
{
320 321 322 323
	if (self->dict == NULL) {
		PyErr_SetString(PyExc_AttributeError, "__dict__");
		return NULL;
	}
324

325 326
	Py_INCREF(self->dict);
	return self->dict;
327 328 329
}

static PyGetSetDef local_getset[] = {
330 331 332
	{"__dict__", (getter)local_getdict, (setter)NULL,
	 "Local-data dictionary", NULL},
	{NULL}  /* Sentinel */
333 334
};

335 336
static PyObject *local_getattro(localobject *, PyObject *);

337
static PyTypeObject localtype = {
338
	PyVarObject_HEAD_INIT(NULL, 0)
339
	/* tp_name           */ "_thread._local",
340 341 342
	/* tp_basicsize      */ sizeof(localobject),
	/* tp_itemsize       */ 0,
	/* tp_dealloc        */ (destructor)local_dealloc,
343 344 345 346 347
	/* tp_print          */ 0,
	/* tp_getattr        */ 0,
	/* tp_setattr        */ 0,
	/* tp_compare        */ 0,
	/* tp_repr           */ 0,
348 349 350
	/* tp_as_number      */ 0,
	/* tp_as_sequence    */ 0,
	/* tp_as_mapping     */ 0,
351 352 353
	/* tp_hash           */ 0,
	/* tp_call           */ 0,
	/* tp_str            */ 0,
354 355 356 357
	/* tp_getattro       */ (getattrofunc)local_getattro,
	/* tp_setattro       */ (setattrofunc)local_setattro,
	/* tp_as_buffer      */ 0,
	/* tp_flags          */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
358
	/* tp_doc            */ "Thread-local data",
359 360
	/* tp_traverse       */ (traverseproc)local_traverse,
	/* tp_clear          */ (inquiry)local_clear,
361 362 363 364
	/* tp_richcompare    */ 0,
	/* tp_weaklistoffset */ 0,
	/* tp_iter           */ 0,
	/* tp_iternext       */ 0,
365 366 367 368 369
	/* tp_methods        */ 0,
	/* tp_members        */ 0,
	/* tp_getset         */ local_getset,
	/* tp_base           */ 0,
	/* tp_dict           */ 0, /* internal use */
370 371
	/* tp_descr_get      */ 0,
	/* tp_descr_set      */ 0,
372
	/* tp_dictoffset     */ offsetof(localobject, dict),
373 374 375
	/* tp_init           */ 0,
	/* tp_alloc          */ 0,
	/* tp_new            */ local_new,
376
	/* tp_free           */ 0, /* Low-level free-mem routine */
377
	/* tp_is_gc          */ 0, /* For PyObject_IS_GC */
378 379
};

380 381 382 383 384 385 386 387 388
static PyObject *
local_getattro(localobject *self, PyObject *name)
{
	PyObject *ldict, *value;

	ldict = _ldict(self);
	if (ldict == NULL) 
		return NULL;

389
	if (Py_TYPE(self) != &localtype)
390 391 392 393 394 395 396 397 398 399 400 401
		/* use generic lookup for subtypes */
		return PyObject_GenericGetAttr((PyObject *)self, name);

	/* Optimization: just look in dict ourselves */
	value = PyDict_GetItem(ldict, name);
	if (value == NULL) 
		/* Fall back on generic to get __class__ and __dict__ */
		return PyObject_GenericGetAttr((PyObject *)self, name);

	Py_INCREF(value);
	return value;
}
402 403 404

/* Module functions */

405 406 407 408 409 410 411
struct bootstate {
	PyInterpreterState *interp;
	PyObject *func;
	PyObject *args;
	PyObject *keyw;
};

412
static void
Peter Schneider-Kamp's avatar
Peter Schneider-Kamp committed
413
t_bootstrap(void *boot_raw)
414
{
415
	struct bootstate *boot = (struct bootstate *) boot_raw;
Michael W. Hudson's avatar
Michael W. Hudson committed
416
	PyThreadState *tstate;
417
	PyObject *res;
418

Michael W. Hudson's avatar
Michael W. Hudson committed
419 420 421
	tstate = PyThreadState_New(boot->interp);

	PyEval_AcquireThread(tstate);
422 423
	res = PyEval_CallObjectWithKeywords(
		boot->func, boot->args, boot->keyw);
424
	if (res == NULL) {
425
		if (PyErr_ExceptionMatches(PyExc_SystemExit))
Barry Warsaw's avatar
Barry Warsaw committed
426
			PyErr_Clear();
427
		else {
428 429 430 431
			PyObject *file;
			PySys_WriteStderr(
				"Unhandled exception in thread started by ");
			file = PySys_GetObject("stderr");
432
			if (file != NULL && file != Py_None)
433 434 435 436
				PyFile_WriteObject(boot->func, file, 0);
			else
				PyObject_Print(boot->func, stderr, 0);
			PySys_WriteStderr("\n");
437
			PyErr_PrintEx(0);
438
		}
439
	}
440
	else
Barry Warsaw's avatar
Barry Warsaw committed
441
		Py_DECREF(res);
442 443 444 445
	Py_DECREF(boot->func);
	Py_DECREF(boot->args);
	Py_XDECREF(boot->keyw);
	PyMem_DEL(boot_raw);
Michael W. Hudson's avatar
Michael W. Hudson committed
446 447
	PyThreadState_Clear(tstate);
	PyThreadState_DeleteCurrent();
448
	PyThread_exit_thread();
449 450
}

Barry Warsaw's avatar
Barry Warsaw committed
451
static PyObject *
Peter Schneider-Kamp's avatar
Peter Schneider-Kamp committed
452
thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
453
{
454
	PyObject *func, *args, *keyw = NULL;
455
	struct bootstate *boot;
456
	long ident;
457

458 459
	if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
		               &func, &args, &keyw))
460 461 462 463
		return NULL;
	if (!PyCallable_Check(func)) {
		PyErr_SetString(PyExc_TypeError,
				"first arg must be callable");
464
		return NULL;
465 466 467
	}
	if (!PyTuple_Check(args)) {
		PyErr_SetString(PyExc_TypeError,
468
				"2nd arg must be a tuple");
469 470 471 472 473 474 475 476 477 478
		return NULL;
	}
	if (keyw != NULL && !PyDict_Check(keyw)) {
		PyErr_SetString(PyExc_TypeError,
				"optional 3rd arg must be a dictionary");
		return NULL;
	}
	boot = PyMem_NEW(struct bootstate, 1);
	if (boot == NULL)
		return PyErr_NoMemory();
479
	boot->interp = PyThreadState_GET()->interp;
480 481 482 483
	boot->func = func;
	boot->args = args;
	boot->keyw = keyw;
	Py_INCREF(func);
Barry Warsaw's avatar
Barry Warsaw committed
484
	Py_INCREF(args);
485 486
	Py_XINCREF(keyw);
	PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
487 488
	ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
	if (ident == -1) {
489
		PyErr_SetString(ThreadError, "can't start new thread");
490 491 492 493
		Py_DECREF(func);
		Py_DECREF(args);
		Py_XDECREF(keyw);
		PyMem_DEL(boot);
494 495
		return NULL;
	}
496
	return PyLong_FromLong(ident);
497 498
}

499
PyDoc_STRVAR(start_new_doc,
500
"start_new_thread(function, args[, kwargs])\n\
501 502
(start_new() is an obsolete synonym)\n\
\n\
503 504 505 506 507
Start a new thread and return its identifier.  The thread will call the\n\
function with positional arguments from the tuple args and keyword arguments\n\
taken from the optional dictionary kwargs.  The thread exits when the\n\
function returns; the return value is ignored.  The thread will also exit\n\
when the function raises an unhandled exception; a stack trace will be\n\
508
printed unless the exception is SystemExit.\n");
509

Barry Warsaw's avatar
Barry Warsaw committed
510
static PyObject *
511
thread_PyThread_exit_thread(PyObject *self)
512
{
Barry Warsaw's avatar
Barry Warsaw committed
513
	PyErr_SetNone(PyExc_SystemExit);
514
	return NULL;
515 516
}

517
PyDoc_STRVAR(exit_doc,
518
"exit()\n\
519
(PyThread_exit_thread() is an obsolete synonym)\n\
520 521
\n\
This is synonymous to ``raise SystemExit''.  It will cause the current\n\
522
thread to exit silently unless the exception is caught.");
523

524
static PyObject *
Kurt B. Kaiser's avatar
Kurt B. Kaiser committed
525
thread_PyThread_interrupt_main(PyObject * self)
526 527 528 529 530 531 532 533 534 535
{
	PyErr_SetInterrupt();
	Py_INCREF(Py_None);
	return Py_None;
}

PyDoc_STRVAR(interrupt_doc,
"interrupt_main()\n\
\n\
Raise a KeyboardInterrupt in the main thread.\n\
Kurt B. Kaiser's avatar
Kurt B. Kaiser committed
536
A subthread can use this function to interrupt the main thread."
537 538
);

539
#ifndef NO_EXIT_PROG
Barry Warsaw's avatar
Barry Warsaw committed
540
static PyObject *
Peter Schneider-Kamp's avatar
Peter Schneider-Kamp committed
541
thread_PyThread_exit_prog(PyObject *self, PyObject *args)
542 543
{
	int sts;
Neal Norwitz's avatar
Neal Norwitz committed
544
	if (!PyArg_ParseTuple(args, "i:exit_prog", &sts))
545
		return NULL;
546
	Py_Exit(sts); /* Calls PyThread_exit_prog(sts) or _PyThread_exit_prog(sts) */
547 548
	for (;;) { } /* Should not be reached */
}
549
#endif
550

551 552
static lockobject *newlockobject(void);

Barry Warsaw's avatar
Barry Warsaw committed
553
static PyObject *
554
thread_PyThread_allocate_lock(PyObject *self)
555
{
Barry Warsaw's avatar
Barry Warsaw committed
556
	return (PyObject *) newlockobject();
557 558
}

559
PyDoc_STRVAR(allocate_doc,
560 561 562
"allocate_lock() -> lock object\n\
(allocate() is an obsolete synonym)\n\
\n\
563
Create a new lock object.  See LockType.__doc__ for information about locks.");
564

Barry Warsaw's avatar
Barry Warsaw committed
565
static PyObject *
566
thread_get_ident(PyObject *self)
567 568
{
	long ident;
569
	ident = PyThread_get_thread_ident();
570
	if (ident == -1) {
Barry Warsaw's avatar
Barry Warsaw committed
571
		PyErr_SetString(ThreadError, "no current thread ident");
572 573
		return NULL;
	}
574
	return PyLong_FromLong(ident);
575 576
}

577
PyDoc_STRVAR(get_ident_doc,
578 579 580 581 582 583 584 585
"get_ident() -> integer\n\
\n\
Return a non-zero integer that uniquely identifies the current thread\n\
amongst other threads that exist simultaneously.\n\
This may be used to identify per-thread resources.\n\
Even though on some platforms threads identities may appear to be\n\
allocated consecutive numbers starting at 1, this behavior should not\n\
be relied upon, and the number should be seen purely as a magic cookie.\n\
586
A thread's identity may be reused for another thread after it exits.");
587

588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618
static PyObject *
thread_stack_size(PyObject *self, PyObject *args)
{
	size_t old_size;
	Py_ssize_t new_size = 0;
	int rc;

	if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
		return NULL;

	if (new_size < 0) {
		PyErr_SetString(PyExc_ValueError,
				"size must be 0 or a positive value");
		return NULL;
	}

	old_size = PyThread_get_stacksize();

	rc = PyThread_set_stacksize((size_t) new_size);
	if (rc == -1) {
		PyErr_Format(PyExc_ValueError,
			     "size not valid: %zd bytes",
			     new_size);
		return NULL;
	}
	if (rc == -2) {
		PyErr_SetString(ThreadError,
				"setting stack size not supported");
		return NULL;
	}

619
	return PyLong_FromSsize_t((Py_ssize_t) old_size);
620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641
}

PyDoc_STRVAR(stack_size_doc,
"stack_size([size]) -> size\n\
\n\
Return the thread stack size used when creating new threads.  The\n\
optional size argument specifies the stack size (in bytes) to be used\n\
for subsequently created threads, and must be 0 (use platform or\n\
configured default) or a positive integer value of at least 32,768 (32k).\n\
If changing the thread stack size is unsupported, a ThreadError\n\
exception is raised.  If the specified size is invalid, a ValueError\n\
exception is raised, and the stack size is unmodified.  32k bytes\n\
 currently the minimum supported stack size value to guarantee\n\
sufficient stack space for the interpreter itself.\n\
\n\
Note that some platforms may have particular restrictions on values for\n\
the stack size, such as requiring a minimum stack size larger than 32kB or\n\
requiring allocation in multiples of the system memory page size\n\
- platform documentation should be referred to for more information\n\
(4kB pages are common; using multiples of 4096 for the stack size is\n\
the suggested approach in the absence of more specific information).");

Barry Warsaw's avatar
Barry Warsaw committed
642
static PyMethodDef thread_methods[] = {
643 644
	{"start_new_thread",	(PyCFunction)thread_PyThread_start_new_thread,
	                        METH_VARARGS,
645
				start_new_doc},
646 647
	{"start_new",		(PyCFunction)thread_PyThread_start_new_thread, 
	                        METH_VARARGS,
648
				start_new_doc},
649
	{"allocate_lock",	(PyCFunction)thread_PyThread_allocate_lock, 
650
	 METH_NOARGS, allocate_doc},
651
	{"allocate",		(PyCFunction)thread_PyThread_allocate_lock, 
652
	 METH_NOARGS, allocate_doc},
653
	{"exit_thread",		(PyCFunction)thread_PyThread_exit_thread, 
654
	 METH_NOARGS, exit_doc},
655
	{"exit",		(PyCFunction)thread_PyThread_exit_thread, 
656
	 METH_NOARGS, exit_doc},
Kurt B. Kaiser's avatar
Kurt B. Kaiser committed
657
	{"interrupt_main",	(PyCFunction)thread_PyThread_interrupt_main,
658
	 METH_NOARGS, interrupt_doc},
659
	{"get_ident",		(PyCFunction)thread_get_ident, 
660
	 METH_NOARGS, get_ident_doc},
661 662 663
	{"stack_size",		(PyCFunction)thread_stack_size,
				METH_VARARGS,
				stack_size_doc},
664
#ifndef NO_EXIT_PROG
Neal Norwitz's avatar
Neal Norwitz committed
665 666
	{"exit_prog",		(PyCFunction)thread_PyThread_exit_prog,
	 METH_VARARGS},
667
#endif
668 669 670 671 672 673
	{NULL,			NULL}		/* sentinel */
};


/* Initialization function */

674
PyDoc_STRVAR(thread_doc,
675
"This module provides primitive operations to write multi-threaded programs.\n\
676
The 'threading' module provides a more convenient interface.");
677

678
PyDoc_STRVAR(lock_doc,
679
"A lock object is a synchronization primitive.  To create a lock,\n\
680
call the PyThread_allocate_lock() function.  Methods are:\n\
681 682 683 684 685 686 687
\n\
acquire() -- lock the lock, possibly blocking until it can be obtained\n\
release() -- unlock of the lock\n\
locked() -- test whether the lock is currently locked\n\
\n\
A lock is not owned by the thread that locked it; another thread may\n\
unlock it.  A thread attempting to lock a lock that it has already locked\n\
688
will block until another thread unlocks it.  Deadlocks may ensue.");
689

690
PyMODINIT_FUNC
691
init_thread(void)
692
{
Barry Warsaw's avatar
Barry Warsaw committed
693
	PyObject *m, *d;
694 695 696 697
	
	/* Initialize types: */
	if (PyType_Ready(&localtype) < 0)
		return;
698 699
	if (PyType_Ready(&Locktype) < 0)
		return;
700 701

	/* Create the module and add the functions */
702
	m = Py_InitModule3("_thread", thread_methods, thread_doc);
703 704
	if (m == NULL)
		return;
705 706

	/* Add a symbolic constant */
Barry Warsaw's avatar
Barry Warsaw committed
707
	d = PyModule_GetDict(m);
708
	ThreadError = PyErr_NewException("_thread.error", NULL, NULL);
Barry Warsaw's avatar
Barry Warsaw committed
709
	PyDict_SetItemString(d, "error", ThreadError);
710 711 712
	Locktype.tp_doc = lock_doc;
	Py_INCREF(&Locktype);
	PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);
713

714
	Py_INCREF(&localtype);
715 716
	if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
		return;
717

718
	/* Initialize the C thread library */
719
	PyThread_init_thread();
720
}