_threadmodule.c 44.1 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
#include "pycore_pystate.h"
7
#include "structmember.h" /* offsetof */
8
#include "pythread.h"
9

Barry Warsaw's avatar
Barry Warsaw committed
10
static PyObject *ThreadError;
11
static PyObject *str_dict;
12

13 14
_Py_IDENTIFIER(stderr);

15 16 17
/* Lock objects */

typedef struct {
18 19 20
    PyObject_HEAD
    PyThread_type_lock lock_lock;
    PyObject *in_weakreflist;
21
    char locked; /* for sanity checking */
22 23 24
} lockobject;

static void
Peter Schneider-Kamp's avatar
Peter Schneider-Kamp committed
25
lock_dealloc(lockobject *self)
26
{
27 28 29 30
    if (self->in_weakreflist != NULL)
        PyObject_ClearWeakRefs((PyObject *) self);
    if (self->lock_lock != NULL) {
        /* Unlock the lock so it's safe to free it */
31 32
        if (self->locked)
            PyThread_release_lock(self->lock_lock);
33 34 35
        PyThread_free_lock(self->lock_lock);
    }
    PyObject_Del(self);
36 37
}

38 39 40
/* Helper to acquire an interruptible lock with a timeout.  If the lock acquire
 * is interrupted, signal handlers are run, and if they raise an exception,
 * PY_LOCK_INTR is returned.  Otherwise, PY_LOCK_ACQUIRED or PY_LOCK_FAILURE
41
 * are returned, depending on whether the lock can be acquired within the
42 43 44
 * timeout.
 */
static PyLockStatus
45
acquire_timed(PyThread_type_lock lock, _PyTime_t timeout)
46 47
{
    PyLockStatus r;
48 49
    _PyTime_t endtime = 0;
    _PyTime_t microseconds;
50

51 52
    if (timeout > 0)
        endtime = _PyTime_GetMonotonicClock() + timeout;
53 54

    do {
55
        microseconds = _PyTime_AsMicroseconds(timeout, _PyTime_ROUND_CEILING);
56

57 58 59 60 61 62
        /* first a simple non-blocking try without releasing the GIL */
        r = PyThread_acquire_lock_timed(lock, 0, 0);
        if (r == PY_LOCK_FAILURE && microseconds != 0) {
            Py_BEGIN_ALLOW_THREADS
            r = PyThread_acquire_lock_timed(lock, microseconds, 1);
            Py_END_ALLOW_THREADS
63
        }
64 65 66 67 68 69 70 71 72 73 74

        if (r == PY_LOCK_INTR) {
            /* Run signal handlers if we were interrupted.  Propagate
             * exceptions from signal handlers, such as KeyboardInterrupt, by
             * passing up PY_LOCK_INTR.  */
            if (Py_MakePendingCalls() < 0) {
                return PY_LOCK_INTR;
            }

            /* If we're using a timeout, recompute the timeout after processing
             * signals, since those can take time.  */
75 76
            if (timeout > 0) {
                timeout = endtime - _PyTime_GetMonotonicClock();
77 78 79

                /* Check for negative values, since those mean block forever.
                 */
80
                if (timeout < 0) {
81 82 83 84 85 86 87 88 89
                    r = PY_LOCK_FAILURE;
                }
            }
        }
    } while (r == PY_LOCK_INTR);  /* Retry if we were interrupted. */

    return r;
}

90 91 92
static int
lock_acquire_parse_args(PyObject *args, PyObject *kwds,
                        _PyTime_t *timeout)
93
{
94 95
    char *kwlist[] = {"blocking", "timeout", NULL};
    int blocking = 1;
96
    PyObject *timeout_obj = NULL;
97
    const _PyTime_t unset_timeout = _PyTime_FromSeconds(-1);
98

99
    *timeout = unset_timeout ;
100

101 102 103 104 105
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO:acquire", kwlist,
                                     &blocking, &timeout_obj))
        return -1;

    if (timeout_obj
106
        && _PyTime_FromSecondsObject(timeout,
107
                                     timeout_obj, _PyTime_ROUND_TIMEOUT) < 0)
108 109 110 111 112 113
        return -1;

    if (!blocking && *timeout != unset_timeout ) {
        PyErr_SetString(PyExc_ValueError,
                        "can't specify a timeout for a non-blocking call");
        return -1;
114
    }
115 116 117 118
    if (*timeout < 0 && *timeout != unset_timeout) {
        PyErr_SetString(PyExc_ValueError,
                        "timeout value must be positive");
        return -1;
119 120
    }
    if (!blocking)
121 122 123 124
        *timeout = 0;
    else if (*timeout != unset_timeout) {
        _PyTime_t microseconds;

125
        microseconds = _PyTime_AsMicroseconds(*timeout, _PyTime_ROUND_TIMEOUT);
126
        if (microseconds >= PY_TIMEOUT_MAX) {
127 128
            PyErr_SetString(PyExc_OverflowError,
                            "timeout value is too large");
129
            return -1;
130 131
        }
    }
132 133 134 135 136 137 138 139
    return 0;
}

static PyObject *
lock_PyThread_acquire_lock(lockobject *self, PyObject *args, PyObject *kwds)
{
    _PyTime_t timeout;
    PyLockStatus r;
140

141 142 143 144
    if (lock_acquire_parse_args(args, kwds, &timeout) < 0)
        return NULL;

    r = acquire_timed(self->lock_lock, timeout);
145 146 147
    if (r == PY_LOCK_INTR) {
        return NULL;
    }
148

149 150
    if (r == PY_LOCK_ACQUIRED)
        self->locked = 1;
151
    return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
152 153
}

154
PyDoc_STRVAR(acquire_doc,
155
"acquire(blocking=True, timeout=-1) -> bool\n\
156
(acquire_lock() is an obsolete synonym)\n\
157 158 159
\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\
160
the lock, and return True once the lock is acquired.\n\
161
With an argument, this will only block if the argument is true,\n\
162
and the return value reflects whether the lock is acquired.\n\
163
The blocking operation is interruptible.");
164

Barry Warsaw's avatar
Barry Warsaw committed
165
static PyObject *
166
lock_PyThread_release_lock(lockobject *self, PyObject *Py_UNUSED(ignored))
167
{
168
    /* Sanity check: the lock must be locked */
169
    if (!self->locked) {
170 171 172 173 174
        PyErr_SetString(ThreadError, "release unlocked lock");
        return NULL;
    }

    PyThread_release_lock(self->lock_lock);
175
    self->locked = 0;
176
    Py_RETURN_NONE;
177 178
}

179
PyDoc_STRVAR(release_doc,
180
"release()\n\
181
(release_lock() is an obsolete synonym)\n\
182 183 184
\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\
185
but it needn't be locked by the same thread that unlocks it.");
186

Barry Warsaw's avatar
Barry Warsaw committed
187
static PyObject *
188
lock_locked_lock(lockobject *self, PyObject *Py_UNUSED(ignored))
189
{
190
    return PyBool_FromLong((long)self->locked);
191 192
}

193
PyDoc_STRVAR(locked_doc,
194
"locked() -> bool\n\
195 196
(locked_lock() is an obsolete synonym)\n\
\n\
197
Return whether the lock is in the locked state.");
198

199 200 201 202 203 204 205
static PyObject *
lock_repr(lockobject *self)
{
    return PyUnicode_FromFormat("<%s %s object at %p>",
        self->locked ? "locked" : "unlocked", Py_TYPE(self)->tp_name, self);
}

Barry Warsaw's avatar
Barry Warsaw committed
206
static PyMethodDef lock_methods[] = {
207
    {"acquire_lock", (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock,
208
     METH_VARARGS | METH_KEYWORDS, acquire_doc},
209
    {"acquire",      (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock,
210 211 212 213 214 215 216 217 218
     METH_VARARGS | METH_KEYWORDS, acquire_doc},
    {"release_lock", (PyCFunction)lock_PyThread_release_lock,
     METH_NOARGS, release_doc},
    {"release",      (PyCFunction)lock_PyThread_release_lock,
     METH_NOARGS, release_doc},
    {"locked_lock",  (PyCFunction)lock_locked_lock,
     METH_NOARGS, locked_doc},
    {"locked",       (PyCFunction)lock_locked_lock,
     METH_NOARGS, locked_doc},
219
    {"__enter__",    (PyCFunction)(void(*)(void))lock_PyThread_acquire_lock,
220 221 222 223
     METH_VARARGS | METH_KEYWORDS, acquire_doc},
    {"__exit__",    (PyCFunction)lock_PyThread_release_lock,
     METH_VARARGS, release_doc},
    {NULL,           NULL}              /* sentinel */
224 225
};

Barry Warsaw's avatar
Barry Warsaw committed
226
static PyTypeObject Locktype = {
227 228
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "_thread.lock",                     /*tp_name*/
229
    sizeof(lockobject),                 /*tp_basicsize*/
230 231 232 233 234 235 236
    0,                                  /*tp_itemsize*/
    /* methods */
    (destructor)lock_dealloc,           /*tp_dealloc*/
    0,                                  /*tp_print*/
    0,                                  /*tp_getattr*/
    0,                                  /*tp_setattr*/
    0,                                  /*tp_reserved*/
237
    (reprfunc)lock_repr,                /*tp_repr*/
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
    0,                                  /*tp_as_number*/
    0,                                  /*tp_as_sequence*/
    0,                                  /*tp_as_mapping*/
    0,                                  /*tp_hash*/
    0,                                  /*tp_call*/
    0,                                  /*tp_str*/
    0,                                  /*tp_getattro*/
    0,                                  /*tp_setattro*/
    0,                                  /*tp_as_buffer*/
    Py_TPFLAGS_DEFAULT,                 /*tp_flags*/
    0,                                  /*tp_doc*/
    0,                                  /*tp_traverse*/
    0,                                  /*tp_clear*/
    0,                                  /*tp_richcompare*/
    offsetof(lockobject, in_weakreflist), /*tp_weaklistoffset*/
    0,                                  /*tp_iter*/
    0,                                  /*tp_iternext*/
    lock_methods,                       /*tp_methods*/
256 257
};

258 259 260
/* Recursive lock objects */

typedef struct {
261 262
    PyObject_HEAD
    PyThread_type_lock rlock_lock;
263
    unsigned long rlock_owner;
264 265
    unsigned long rlock_count;
    PyObject *in_weakreflist;
266 267 268 269 270
} rlockobject;

static void
rlock_dealloc(rlockobject *self)
{
271 272
    if (self->in_weakreflist != NULL)
        PyObject_ClearWeakRefs((PyObject *) self);
273 274 275 276 277 278
    /* self->rlock_lock can be NULL if PyThread_allocate_lock() failed
       in rlock_new() */
    if (self->rlock_lock != NULL) {
        /* Unlock the lock so it's safe to free it */
        if (self->rlock_count > 0)
            PyThread_release_lock(self->rlock_lock);
279

280 281
        PyThread_free_lock(self->rlock_lock);
    }
282
    Py_TYPE(self)->tp_free(self);
283 284 285 286 287
}

static PyObject *
rlock_acquire(rlockobject *self, PyObject *args, PyObject *kwds)
{
288
    _PyTime_t timeout;
289
    unsigned long tid;
290
    PyLockStatus r = PY_LOCK_ACQUIRED;
291

292
    if (lock_acquire_parse_args(args, kwds, &timeout) < 0)
293 294 295 296 297 298 299 300 301 302 303 304 305
        return NULL;

    tid = PyThread_get_thread_ident();
    if (self->rlock_count > 0 && tid == self->rlock_owner) {
        unsigned long count = self->rlock_count + 1;
        if (count <= self->rlock_count) {
            PyErr_SetString(PyExc_OverflowError,
                            "Internal lock count overflowed");
            return NULL;
        }
        self->rlock_count = count;
        Py_RETURN_TRUE;
    }
306
    r = acquire_timed(self->rlock_lock, timeout);
307
    if (r == PY_LOCK_ACQUIRED) {
308 309 310 311
        assert(self->rlock_count == 0);
        self->rlock_owner = tid;
        self->rlock_count = 1;
    }
312 313 314
    else if (r == PY_LOCK_INTR) {
        return NULL;
    }
315

316
    return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
317 318 319 320 321 322 323 324 325 326 327
}

PyDoc_STRVAR(rlock_acquire_doc,
"acquire(blocking=True) -> bool\n\
\n\
Lock the lock.  `blocking` indicates whether we should wait\n\
for the lock to be available or not.  If `blocking` is False\n\
and another thread holds the lock, the method will return False\n\
immediately.  If `blocking` is True and another thread holds\n\
the lock, the method will wait for the lock to be released,\n\
take it and then return True.\n\
328
(note: the blocking operation is interruptible.)\n\
329 330 331 332 333 334 335
\n\
In all other cases, the method will return True immediately.\n\
Precisely, if the current thread already holds the lock, its\n\
internal counter is simply incremented. If nobody holds the lock,\n\
the lock is taken and its internal counter initialized to 1.");

static PyObject *
336
rlock_release(rlockobject *self, PyObject *Py_UNUSED(ignored))
337
{
338
    unsigned long tid = PyThread_get_thread_ident();
339 340 341 342 343 344 345 346 347 348 349

    if (self->rlock_count == 0 || self->rlock_owner != tid) {
        PyErr_SetString(PyExc_RuntimeError,
                        "cannot release un-acquired lock");
        return NULL;
    }
    if (--self->rlock_count == 0) {
        self->rlock_owner = 0;
        PyThread_release_lock(self->rlock_lock);
    }
    Py_RETURN_NONE;
350 351 352 353 354 355 356 357 358 359 360 361 362 363 364
}

PyDoc_STRVAR(rlock_release_doc,
"release()\n\
\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\
and must be locked by the same thread that unlocks it; otherwise a\n\
`RuntimeError` is raised.\n\
\n\
Do note that if the lock was acquire()d several times in a row by the\n\
current thread, release() needs to be called as many times for the lock\n\
to be available for other threads.");

static PyObject *
365
rlock_acquire_restore(rlockobject *self, PyObject *args)
366
{
367
    unsigned long owner;
368 369 370
    unsigned long count;
    int r = 1;

371
    if (!PyArg_ParseTuple(args, "(kk):_acquire_restore", &count, &owner))
372 373 374 375 376 377 378 379 380 381 382 383 384 385 386
        return NULL;

    if (!PyThread_acquire_lock(self->rlock_lock, 0)) {
        Py_BEGIN_ALLOW_THREADS
        r = PyThread_acquire_lock(self->rlock_lock, 1);
        Py_END_ALLOW_THREADS
    }
    if (!r) {
        PyErr_SetString(ThreadError, "couldn't acquire lock");
        return NULL;
    }
    assert(self->rlock_count == 0);
    self->rlock_owner = owner;
    self->rlock_count = count;
    Py_RETURN_NONE;
387 388 389 390 391 392 393 394
}

PyDoc_STRVAR(rlock_acquire_restore_doc,
"_acquire_restore(state) -> None\n\
\n\
For internal use by `threading.Condition`.");

static PyObject *
395
rlock_release_save(rlockobject *self, PyObject *Py_UNUSED(ignored))
396
{
397
    unsigned long owner;
398 399
    unsigned long count;

400 401 402 403 404 405
    if (self->rlock_count == 0) {
        PyErr_SetString(PyExc_RuntimeError,
                        "cannot release un-acquired lock");
        return NULL;
    }

406 407 408 409 410
    owner = self->rlock_owner;
    count = self->rlock_count;
    self->rlock_count = 0;
    self->rlock_owner = 0;
    PyThread_release_lock(self->rlock_lock);
411
    return Py_BuildValue("kk", count, owner);
412 413 414 415 416 417 418 419 420
}

PyDoc_STRVAR(rlock_release_save_doc,
"_release_save() -> tuple\n\
\n\
For internal use by `threading.Condition`.");


static PyObject *
421
rlock_is_owned(rlockobject *self, PyObject *Py_UNUSED(ignored))
422
{
423
    unsigned long tid = PyThread_get_thread_ident();
424 425 426 427 428

    if (self->rlock_count > 0 && self->rlock_owner == tid) {
        Py_RETURN_TRUE;
    }
    Py_RETURN_FALSE;
429 430 431 432 433 434 435 436 437 438
}

PyDoc_STRVAR(rlock_is_owned_doc,
"_is_owned() -> bool\n\
\n\
For internal use by `threading.Condition`.");

static PyObject *
rlock_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
439 440 441 442
    rlockobject *self;

    self = (rlockobject *) type->tp_alloc(type, 0);
    if (self != NULL) {
443 444 445 446
        self->in_weakreflist = NULL;
        self->rlock_owner = 0;
        self->rlock_count = 0;

447 448
        self->rlock_lock = PyThread_allocate_lock();
        if (self->rlock_lock == NULL) {
449
            Py_DECREF(self);
450 451 452 453 454 455
            PyErr_SetString(ThreadError, "can't allocate lock");
            return NULL;
        }
    }

    return (PyObject *) self;
456 457 458 459 460
}

static PyObject *
rlock_repr(rlockobject *self)
{
461 462 463 464
    return PyUnicode_FromFormat("<%s %s object owner=%ld count=%lu at %p>",
        self->rlock_count ? "locked" : "unlocked",
        Py_TYPE(self)->tp_name, self->rlock_owner,
        self->rlock_count, self);
465 466 467 468
}


static PyMethodDef rlock_methods[] = {
469
    {"acquire",      (PyCFunction)(void(*)(void))rlock_acquire,
470 471 472 473 474 475
     METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
    {"release",      (PyCFunction)rlock_release,
     METH_NOARGS, rlock_release_doc},
    {"_is_owned",     (PyCFunction)rlock_is_owned,
     METH_NOARGS, rlock_is_owned_doc},
    {"_acquire_restore", (PyCFunction)rlock_acquire_restore,
476
     METH_VARARGS, rlock_acquire_restore_doc},
477 478
    {"_release_save", (PyCFunction)rlock_release_save,
     METH_NOARGS, rlock_release_save_doc},
479
    {"__enter__",    (PyCFunction)(void(*)(void))rlock_acquire,
480 481 482 483
     METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
    {"__exit__",    (PyCFunction)rlock_release,
     METH_VARARGS, rlock_release_doc},
    {NULL,           NULL}              /* sentinel */
484 485 486 487
};


static PyTypeObject RLocktype = {
488 489
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "_thread.RLock",                    /*tp_name*/
490
    sizeof(rlockobject),                /*tp_basicsize*/
491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526
    0,                                  /*tp_itemsize*/
    /* methods */
    (destructor)rlock_dealloc,          /*tp_dealloc*/
    0,                                  /*tp_print*/
    0,                                  /*tp_getattr*/
    0,                                  /*tp_setattr*/
    0,                                  /*tp_reserved*/
    (reprfunc)rlock_repr,               /*tp_repr*/
    0,                                  /*tp_as_number*/
    0,                                  /*tp_as_sequence*/
    0,                                  /*tp_as_mapping*/
    0,                                  /*tp_hash*/
    0,                                  /*tp_call*/
    0,                                  /*tp_str*/
    0,                                  /*tp_getattro*/
    0,                                  /*tp_setattro*/
    0,                                  /*tp_as_buffer*/
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
    0,                                  /*tp_doc*/
    0,                                  /*tp_traverse*/
    0,                                  /*tp_clear*/
    0,                                  /*tp_richcompare*/
    offsetof(rlockobject, in_weakreflist), /*tp_weaklistoffset*/
    0,                                  /*tp_iter*/
    0,                                  /*tp_iternext*/
    rlock_methods,                      /*tp_methods*/
    0,                                  /* tp_members */
    0,                                  /* tp_getset */
    0,                                  /* tp_base */
    0,                                  /* tp_dict */
    0,                                  /* tp_descr_get */
    0,                                  /* tp_descr_set */
    0,                                  /* tp_dictoffset */
    0,                                  /* tp_init */
    PyType_GenericAlloc,                /* tp_alloc */
    rlock_new                           /* tp_new */
527 528
};

529 530 531
static lockobject *
newlockobject(void)
{
532 533 534 535 536
    lockobject *self;
    self = PyObject_New(lockobject, &Locktype);
    if (self == NULL)
        return NULL;
    self->lock_lock = PyThread_allocate_lock();
537
    self->locked = 0;
538 539 540 541 542 543 544
    self->in_weakreflist = NULL;
    if (self->lock_lock == NULL) {
        Py_DECREF(self);
        PyErr_SetString(ThreadError, "can't allocate lock");
        return NULL;
    }
    return self;
545 546
}

547 548 549 550
/* Thread-local objects */

#include "structmember.h"

551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 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 619 620 621 622 623 624 625 626 627 628 629 630 631 632
/* Quick overview:

   We need to be able to reclaim reference cycles as soon as possible
   (both when a thread is being terminated, or a thread-local object
    becomes unreachable from user data).  Constraints:
   - it must not be possible for thread-state dicts to be involved in
     reference cycles (otherwise the cyclic GC will refuse to consider
     objects referenced from a reachable thread-state dict, even though
     local_dealloc would clear them)
   - the death of a thread-state dict must still imply destruction of the
     corresponding local dicts in all thread-local objects.

   Our implementation uses small "localdummy" objects in order to break
   the reference chain. These trivial objects are hashable (using the
   default scheme of identity hashing) and weakrefable.
   Each thread-state holds a separate localdummy for each local object
   (as a /strong reference/),
   and each thread-local object holds a dict mapping /weak references/
   of localdummies to local dicts.

   Therefore:
   - only the thread-state dict holds a strong reference to the dummies
   - only the thread-local object holds a strong reference to the local dicts
   - only outside objects (application- or library-level) hold strong
     references to the thread-local objects
   - as soon as a thread-state dict is destroyed, the weakref callbacks of all
     dummies attached to that thread are called, and destroy the corresponding
     local dicts from thread-local objects
   - as soon as a thread-local object is destroyed, its local dicts are
     destroyed and its dummies are manually removed from all thread states
   - the GC can do its work correctly when a thread-local object is dangling,
     without any interference from the thread-state dicts

   As an additional optimization, each localdummy holds a borrowed reference
   to the corresponding localdict.  This borrowed reference is only used
   by the thread-local object which has created the localdummy, which should
   guarantee that the localdict still exists when accessed.
*/

typedef struct {
    PyObject_HEAD
    PyObject *localdict;        /* Borrowed reference! */
    PyObject *weakreflist;      /* List of weak references to self */
} localdummyobject;

static void
localdummy_dealloc(localdummyobject *self)
{
    if (self->weakreflist != NULL)
        PyObject_ClearWeakRefs((PyObject *) self);
    Py_TYPE(self)->tp_free((PyObject*)self);
}

static PyTypeObject localdummytype = {
    PyVarObject_HEAD_INIT(NULL, 0)
    /* tp_name           */ "_thread._localdummy",
    /* tp_basicsize      */ sizeof(localdummyobject),
    /* tp_itemsize       */ 0,
    /* tp_dealloc        */ (destructor)localdummy_dealloc,
    /* tp_print          */ 0,
    /* tp_getattr        */ 0,
    /* tp_setattr        */ 0,
    /* tp_reserved       */ 0,
    /* tp_repr           */ 0,
    /* tp_as_number      */ 0,
    /* tp_as_sequence    */ 0,
    /* tp_as_mapping     */ 0,
    /* tp_hash           */ 0,
    /* tp_call           */ 0,
    /* tp_str            */ 0,
    /* tp_getattro       */ 0,
    /* tp_setattro       */ 0,
    /* tp_as_buffer      */ 0,
    /* tp_flags          */ Py_TPFLAGS_DEFAULT,
    /* tp_doc            */ "Thread-local dummy",
    /* tp_traverse       */ 0,
    /* tp_clear          */ 0,
    /* tp_richcompare    */ 0,
    /* tp_weaklistoffset */ offsetof(localdummyobject, weakreflist)
};


633
typedef struct {
634 635 636 637
    PyObject_HEAD
    PyObject *key;
    PyObject *args;
    PyObject *kw;
638 639 640 641 642
    PyObject *weakreflist;      /* List of weak references to self */
    /* A {localdummy weakref -> localdict} dict */
    PyObject *dummies;
    /* The callback for weakrefs to localdummies */
    PyObject *wr_callback;
643 644
} localobject;

645 646 647 648
/* Forward declaration */
static PyObject *_ldict(localobject *self);
static PyObject *_localdummy_destroyed(PyObject *meth_self, PyObject *dummyweakref);

649 650 651
/* Create and register the dummy for the current thread.
   Returns a borrowed reference of the corresponding local dict */
static PyObject *
652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686
_local_create_dummy(localobject *self)
{
    PyObject *tdict, *ldict = NULL, *wr = NULL;
    localdummyobject *dummy = NULL;
    int r;

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

    ldict = PyDict_New();
    if (ldict == NULL)
        goto err;
    dummy = (localdummyobject *) localdummytype.tp_alloc(&localdummytype, 0);
    if (dummy == NULL)
        goto err;
    dummy->localdict = ldict;
    wr = PyWeakref_NewRef((PyObject *) dummy, self->wr_callback);
    if (wr == NULL)
        goto err;

    /* As a side-effect, this will cache the weakref's hash before the
       dummy gets deleted */
    r = PyDict_SetItem(self->dummies, wr, ldict);
    if (r < 0)
        goto err;
    Py_CLEAR(wr);
    r = PyDict_SetItem(tdict, self->key, (PyObject *) dummy);
    if (r < 0)
        goto err;
    Py_CLEAR(dummy);

687 688
    Py_DECREF(ldict);
    return ldict;
689 690 691 692 693

err:
    Py_XDECREF(ldict);
    Py_XDECREF(wr);
    Py_XDECREF(dummy);
694
    return NULL;
695 696
}

697 698 699
static PyObject *
local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
{
700
    localobject *self;
701 702 703 704
    PyObject *wr;
    static PyMethodDef wr_callback_def = {
        "_localdummy_destroyed", (PyCFunction) _localdummy_destroyed, METH_O
    };
705

706 707 708 709 710 711 712 713 714 715 716 717
    if (type->tp_init == PyBaseObject_Type.tp_init) {
        int rc = 0;
        if (args != NULL)
            rc = PyObject_IsTrue(args);
        if (rc == 0 && kw != NULL)
            rc = PyObject_IsTrue(kw);
        if (rc != 0) {
            if (rc > 0)
                PyErr_SetString(PyExc_TypeError,
                          "Initialization arguments are not supported");
            return NULL;
        }
718 719 720 721 722 723 724 725 726 727 728 729 730 731
    }

    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->key = PyUnicode_FromFormat("thread.local.%p", self);
    if (self->key == NULL)
        goto err;

732 733
    self->dummies = PyDict_New();
    if (self->dummies == NULL)
734 735
        goto err;

736 737 738 739 740
    /* We use a weak reference to self in the callback closure
       in order to avoid spurious reference cycles */
    wr = PyWeakref_NewRef((PyObject *) self, NULL);
    if (wr == NULL)
        goto err;
741
    self->wr_callback = PyCFunction_NewEx(&wr_callback_def, wr, NULL);
742 743
    Py_DECREF(wr);
    if (self->wr_callback == NULL)
744 745
        goto err;

746
    if (_local_create_dummy(self) == NULL)
747 748 749
        goto err;

    return (PyObject *)self;
750 751

  err:
752 753
    Py_DECREF(self);
    return NULL;
754 755 756 757 758
}

static int
local_traverse(localobject *self, visitproc visit, void *arg)
{
759 760
    Py_VISIT(self->args);
    Py_VISIT(self->kw);
761
    Py_VISIT(self->dummies);
762
    return 0;
763 764 765 766 767
}

static int
local_clear(localobject *self)
{
768
    PyThreadState *tstate;
769 770
    Py_CLEAR(self->args);
    Py_CLEAR(self->kw);
771 772 773
    Py_CLEAR(self->dummies);
    Py_CLEAR(self->wr_callback);
    /* Remove all strong references to dummies from the thread states */
774 775 776 777 778 779
    if (self->key
        && (tstate = PyThreadState_Get())
        && tstate->interp) {
        for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
            tstate;
            tstate = PyThreadState_Next(tstate))
780 781 782 783 784
            if (tstate->dict && PyDict_GetItem(tstate->dict, self->key)) {
                if (PyDict_DelItem(tstate->dict, self->key)) {
                    PyErr_Clear();
                }
            }
785
    }
786 787 788 789 790 791 792 793 794 795 796 797
    return 0;
}

static void
local_dealloc(localobject *self)
{
    /* Weakrefs must be invalidated right now, otherwise they can be used
       from code called below, which is very dangerous since Py_REFCNT(self) == 0 */
    if (self->weakreflist != NULL)
        PyObject_ClearWeakRefs((PyObject *) self);

    PyObject_GC_UnTrack(self);
798 799

    local_clear(self);
800
    Py_XDECREF(self->key);
801
    Py_TYPE(self)->tp_free((PyObject*)self);
802 803
}

804
/* Returns a borrowed reference to the local dict, creating it if necessary */
805 806 807
static PyObject *
_ldict(localobject *self)
{
808
    PyObject *tdict, *ldict, *dummy;
809 810 811 812 813 814 815 816

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

817
    dummy = PyDict_GetItemWithError(tdict, self->key);
818
    if (dummy == NULL) {
819 820 821
        if (PyErr_Occurred()) {
            return NULL;
        }
822 823
        ldict = _local_create_dummy(self);
        if (ldict == NULL)
824 825 826 827 828 829 830
            return NULL;

        if (Py_TYPE(self)->tp_init != PyBaseObject_Type.tp_init &&
            Py_TYPE(self)->tp_init((PyObject*)self,
                                   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
831
               access */
832 833 834
            PyDict_DelItem(tdict, self->key);
            return NULL;
        }
835 836 837 838
    }
    else {
        assert(Py_TYPE(dummy) == &localdummytype);
        ldict = ((localdummyobject *) dummy)->localdict;
839 840 841
    }

    return ldict;
842 843 844 845 846
}

static int
local_setattro(localobject *self, PyObject *name, PyObject *v)
{
847
    PyObject *ldict;
848
    int r;
849 850 851 852

    ldict = _ldict(self);
    if (ldict == NULL)
        return -1;
853

854 855 856 857 858 859 860 861 862
    r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
    if (r == 1) {
        PyErr_Format(PyExc_AttributeError,
                     "'%.50s' object attribute '%U' is read-only",
                     Py_TYPE(self)->tp_name, name);
        return -1;
    }
    if (r == -1)
        return -1;
863

864
    return _PyObject_GenericSetAttrWithDict((PyObject *)self, name, v, ldict);
865 866
}

867 868
static PyObject *local_getattro(localobject *, PyObject *);

869
static PyTypeObject localtype = {
870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888
    PyVarObject_HEAD_INIT(NULL, 0)
    /* tp_name           */ "_thread._local",
    /* tp_basicsize      */ sizeof(localobject),
    /* tp_itemsize       */ 0,
    /* tp_dealloc        */ (destructor)local_dealloc,
    /* tp_print          */ 0,
    /* tp_getattr        */ 0,
    /* tp_setattr        */ 0,
    /* tp_reserved       */ 0,
    /* tp_repr           */ 0,
    /* tp_as_number      */ 0,
    /* tp_as_sequence    */ 0,
    /* tp_as_mapping     */ 0,
    /* tp_hash           */ 0,
    /* tp_call           */ 0,
    /* tp_str            */ 0,
    /* tp_getattro       */ (getattrofunc)local_getattro,
    /* tp_setattro       */ (setattrofunc)local_setattro,
    /* tp_as_buffer      */ 0,
889 890
    /* tp_flags          */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE
                                               | Py_TPFLAGS_HAVE_GC,
891 892 893 894
    /* tp_doc            */ "Thread-local data",
    /* tp_traverse       */ (traverseproc)local_traverse,
    /* tp_clear          */ (inquiry)local_clear,
    /* tp_richcompare    */ 0,
895
    /* tp_weaklistoffset */ offsetof(localobject, weakreflist),
896 897 898 899
    /* tp_iter           */ 0,
    /* tp_iternext       */ 0,
    /* tp_methods        */ 0,
    /* tp_members        */ 0,
900
    /* tp_getset         */ 0,
901 902 903 904
    /* tp_base           */ 0,
    /* tp_dict           */ 0, /* internal use */
    /* tp_descr_get      */ 0,
    /* tp_descr_set      */ 0,
905
    /* tp_dictoffset     */ 0,
906 907 908 909 910
    /* tp_init           */ 0,
    /* tp_alloc          */ 0,
    /* tp_new            */ local_new,
    /* tp_free           */ 0, /* Low-level free-mem routine */
    /* tp_is_gc          */ 0, /* For PyObject_IS_GC */
911 912
};

913 914 915
static PyObject *
local_getattro(localobject *self, PyObject *name)
{
916
    PyObject *ldict, *value;
917
    int r;
918

919 920 921
    ldict = _ldict(self);
    if (ldict == NULL)
        return NULL;
922

923 924 925 926 927 928 929 930
    r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
    if (r == 1) {
        Py_INCREF(ldict);
        return ldict;
    }
    if (r == -1)
        return NULL;

931 932
    if (Py_TYPE(self) != &localtype)
        /* use generic lookup for subtypes */
933 934
        return _PyObject_GenericGetAttrWithDict(
            (PyObject *)self, name, ldict, 0);
935

936
    /* Optimization: just look in dict ourselves */
937 938 939 940 941 942 943 944 945 946 947
    value = PyDict_GetItemWithError(ldict, name);
    if (value != NULL) {
        Py_INCREF(value);
        return value;
    }
    else if (PyErr_Occurred()) {
        return NULL;
    }
    /* Fall back on generic to get __class__ and __dict__ */
    return _PyObject_GenericGetAttrWithDict(
        (PyObject *)self, name, ldict, 0);
948
}
949

950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966
/* Called when a dummy is destroyed. */
static PyObject *
_localdummy_destroyed(PyObject *localweakref, PyObject *dummyweakref)
{
    PyObject *obj;
    localobject *self;
    assert(PyWeakref_CheckRef(localweakref));
    obj = PyWeakref_GET_OBJECT(localweakref);
    if (obj == Py_None)
        Py_RETURN_NONE;
    Py_INCREF(obj);
    assert(PyObject_TypeCheck(obj, &localtype));
    /* If the thread-local object is still alive and not being cleared,
       remove the corresponding local dict */
    self = (localobject *) obj;
    if (self->dummies != NULL) {
        PyObject *ldict;
967
        ldict = PyDict_GetItemWithError(self->dummies, dummyweakref);
968 969 970 971 972 973 974 975 976 977
        if (ldict != NULL) {
            PyDict_DelItem(self->dummies, dummyweakref);
        }
        if (PyErr_Occurred())
            PyErr_WriteUnraisable(obj);
    }
    Py_DECREF(obj);
    Py_RETURN_NONE;
}

978 979
/* Module functions */

980
struct bootstate {
981 982 983 984 985
    PyInterpreterState *interp;
    PyObject *func;
    PyObject *args;
    PyObject *keyw;
    PyThreadState *tstate;
986 987
};

988
static void
Peter Schneider-Kamp's avatar
Peter Schneider-Kamp committed
989
t_bootstrap(void *boot_raw)
990
{
991 992 993 994 995 996
    struct bootstate *boot = (struct bootstate *) boot_raw;
    PyThreadState *tstate;
    PyObject *res;

    tstate = boot->tstate;
    tstate->thread_id = PyThread_get_thread_ident();
997
    _PyThreadState_Init(&_PyRuntime, tstate);
998
    PyEval_AcquireThread(tstate);
999
    tstate->interp->num_threads++;
1000
    res = PyObject_Call(boot->func, boot->args, boot->keyw);
1001 1002 1003 1004 1005
    if (res == NULL) {
        if (PyErr_ExceptionMatches(PyExc_SystemExit))
            PyErr_Clear();
        else {
            PyObject *file;
1006
            PyObject *exc, *value, *tb;
1007 1008
            PySys_WriteStderr(
                "Unhandled exception in thread started by ");
1009
            PyErr_Fetch(&exc, &value, &tb);
1010
            file = _PySys_GetObjectId(&PyId_stderr);
1011 1012 1013 1014 1015
            if (file != NULL && file != Py_None)
                PyFile_WriteObject(boot->func, file, 0);
            else
                PyObject_Print(boot->func, stderr, 0);
            PySys_WriteStderr("\n");
1016
            PyErr_Restore(exc, value, tb);
1017 1018 1019 1020 1021 1022 1023 1024 1025
            PyErr_PrintEx(0);
        }
    }
    else
        Py_DECREF(res);
    Py_DECREF(boot->func);
    Py_DECREF(boot->args);
    Py_XDECREF(boot->keyw);
    PyMem_DEL(boot_raw);
1026
    tstate->interp->num_threads--;
1027 1028 1029
    PyThreadState_Clear(tstate);
    PyThreadState_DeleteCurrent();
    PyThread_exit_thread();
1030 1031
}

Barry Warsaw's avatar
Barry Warsaw committed
1032
static PyObject *
Peter Schneider-Kamp's avatar
Peter Schneider-Kamp committed
1033
thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
1034
{
1035 1036
    PyObject *func, *args, *keyw = NULL;
    struct bootstate *boot;
1037
    unsigned long ident;
1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059

    if (!PyArg_UnpackTuple(fargs, "start_new_thread", 2, 3,
                           &func, &args, &keyw))
        return NULL;
    if (!PyCallable_Check(func)) {
        PyErr_SetString(PyExc_TypeError,
                        "first arg must be callable");
        return NULL;
    }
    if (!PyTuple_Check(args)) {
        PyErr_SetString(PyExc_TypeError,
                        "2nd arg must be a tuple");
        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();
1060
    boot->interp = _PyInterpreterState_Get();
1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073
    boot->func = func;
    boot->args = args;
    boot->keyw = keyw;
    boot->tstate = _PyThreadState_Prealloc(boot->interp);
    if (boot->tstate == NULL) {
        PyMem_DEL(boot);
        return PyErr_NoMemory();
    }
    Py_INCREF(func);
    Py_INCREF(args);
    Py_XINCREF(keyw);
    PyEval_InitThreads(); /* Start the interpreter's thread-awareness */
    ident = PyThread_start_new_thread(t_bootstrap, (void*) boot);
1074
    if (ident == PYTHREAD_INVALID_THREAD_ID) {
1075 1076 1077 1078 1079 1080 1081 1082
        PyErr_SetString(ThreadError, "can't start new thread");
        Py_DECREF(func);
        Py_DECREF(args);
        Py_XDECREF(keyw);
        PyThreadState_Clear(boot->tstate);
        PyMem_DEL(boot);
        return NULL;
    }
1083
    return PyLong_FromUnsignedLong(ident);
1084 1085
}

1086
PyDoc_STRVAR(start_new_doc,
1087
"start_new_thread(function, args[, kwargs])\n\
1088 1089
(start_new() is an obsolete synonym)\n\
\n\
1090 1091 1092 1093 1094
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\
1095
printed unless the exception is SystemExit.\n");
1096

Barry Warsaw's avatar
Barry Warsaw committed
1097
static PyObject *
1098
thread_PyThread_exit_thread(PyObject *self, PyObject *Py_UNUSED(ignored))
1099
{
1100 1101
    PyErr_SetNone(PyExc_SystemExit);
    return NULL;
1102 1103
}

1104
PyDoc_STRVAR(exit_doc,
1105
"exit()\n\
1106
(exit_thread() is an obsolete synonym)\n\
1107 1108
\n\
This is synonymous to ``raise SystemExit''.  It will cause the current\n\
1109
thread to exit silently unless the exception is caught.");
1110

1111
static PyObject *
1112
thread_PyThread_interrupt_main(PyObject * self, PyObject *Py_UNUSED(ignored))
1113
{
1114
    PyErr_SetInterrupt();
1115
    Py_RETURN_NONE;
1116 1117 1118 1119 1120 1121
}

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
1122
A subthread can use this function to interrupt the main thread."
1123 1124
);

1125 1126
static lockobject *newlockobject(void);

Barry Warsaw's avatar
Barry Warsaw committed
1127
static PyObject *
1128
thread_PyThread_allocate_lock(PyObject *self, PyObject *Py_UNUSED(ignored))
1129
{
1130
    return (PyObject *) newlockobject();
1131 1132
}

1133
PyDoc_STRVAR(allocate_doc,
1134 1135 1136
"allocate_lock() -> lock object\n\
(allocate() is an obsolete synonym)\n\
\n\
1137 1138
Create a new lock object. See help(type(threading.Lock())) for\n\
information about locks.");
1139

Barry Warsaw's avatar
Barry Warsaw committed
1140
static PyObject *
1141
thread_get_ident(PyObject *self, PyObject *Py_UNUSED(ignored))
1142
{
1143 1144
    unsigned long ident = PyThread_get_thread_ident();
    if (ident == PYTHREAD_INVALID_THREAD_ID) {
1145 1146 1147
        PyErr_SetString(ThreadError, "no current thread ident");
        return NULL;
    }
1148
    return PyLong_FromUnsignedLong(ident);
1149 1150
}

1151
PyDoc_STRVAR(get_ident_doc,
1152 1153 1154 1155 1156 1157 1158 1159
"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\
1160
A thread's identity may be reused for another thread after it exits.");
1161

1162
static PyObject *
1163
thread__count(PyObject *self, PyObject *Py_UNUSED(ignored))
1164
{
1165 1166
    PyInterpreterState *interp = _PyInterpreterState_Get();
    return PyLong_FromLong(interp->num_threads);
1167 1168 1169 1170 1171
}

PyDoc_STRVAR(_count_doc,
"_count() -> integer\n\
\n\
1172
\
1173
Return the number of currently running Python threads, excluding\n\
1174 1175 1176 1177 1178 1179
the main thread. The returned number comprises all threads created\n\
through `start_new_thread()` as well as `threading.Thread`, and not\n\
yet finished.\n\
\n\
This function is meant for internal and specialized purposes only.\n\
In most applications `threading.enumerate()` should be used instead.");
1180

1181
static void
1182
release_sentinel(void *wr_raw)
1183
{
1184
    PyObject *wr = _PyObject_CAST(wr_raw);
1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203
    /* Tricky: this function is called when the current thread state
       is being deleted.  Therefore, only simple C code can safely
       execute here. */
    PyObject *obj = PyWeakref_GET_OBJECT(wr);
    lockobject *lock;
    if (obj != Py_None) {
        assert(Py_TYPE(obj) == &Locktype);
        lock = (lockobject *) obj;
        if (lock->locked) {
            PyThread_release_lock(lock->lock_lock);
            lock->locked = 0;
        }
    }
    /* Deallocating a weakref with a NULL callback only calls
       PyObject_GC_Del(), which can't call any Python code. */
    Py_DECREF(wr);
}

static PyObject *
1204
thread__set_sentinel(PyObject *self, PyObject *Py_UNUSED(ignored))
1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241
{
    PyObject *wr;
    PyThreadState *tstate = PyThreadState_Get();
    lockobject *lock;

    if (tstate->on_delete_data != NULL) {
        /* We must support the re-creation of the lock from a
           fork()ed child. */
        assert(tstate->on_delete == &release_sentinel);
        wr = (PyObject *) tstate->on_delete_data;
        tstate->on_delete = NULL;
        tstate->on_delete_data = NULL;
        Py_DECREF(wr);
    }
    lock = newlockobject();
    if (lock == NULL)
        return NULL;
    /* The lock is owned by whoever called _set_sentinel(), but the weakref
       hangs to the thread state. */
    wr = PyWeakref_NewRef((PyObject *) lock, NULL);
    if (wr == NULL) {
        Py_DECREF(lock);
        return NULL;
    }
    tstate->on_delete_data = (void *) wr;
    tstate->on_delete = &release_sentinel;
    return (PyObject *) lock;
}

PyDoc_STRVAR(_set_sentinel_doc,
"_set_sentinel() -> lock\n\
\n\
Set a sentinel lock that will be released when the current thread\n\
state is finalized (after it is untied from the interpreter).\n\
\n\
This is a private API for the threading module.");

1242 1243 1244
static PyObject *
thread_stack_size(PyObject *self, PyObject *args)
{
1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273
    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;
    }

    return PyLong_FromSsize_t((Py_ssize_t) old_size);
1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289
}

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\
1290
the stack size, such as requiring a minimum stack size larger than 32 KiB or\n\
1291 1292
requiring allocation in multiples of the system memory page size\n\
- platform documentation should be referred to for more information\n\
1293
(4 KiB pages are common; using multiples of 4096 for the stack size is\n\
1294 1295
the suggested approach in the absence of more specific information).");

Barry Warsaw's avatar
Barry Warsaw committed
1296
static PyMethodDef thread_methods[] = {
1297
    {"start_new_thread",        (PyCFunction)thread_PyThread_start_new_thread,
1298
     METH_VARARGS, start_new_doc},
1299
    {"start_new",               (PyCFunction)thread_PyThread_start_new_thread,
1300
     METH_VARARGS, start_new_doc},
1301
    {"allocate_lock",           thread_PyThread_allocate_lock,
1302
     METH_NOARGS, allocate_doc},
1303
    {"allocate",                thread_PyThread_allocate_lock,
1304
     METH_NOARGS, allocate_doc},
1305
    {"exit_thread",             thread_PyThread_exit_thread,
1306
     METH_NOARGS, exit_doc},
1307
    {"exit",                    thread_PyThread_exit_thread,
1308
     METH_NOARGS, exit_doc},
1309
    {"interrupt_main",          thread_PyThread_interrupt_main,
1310
     METH_NOARGS, interrupt_doc},
1311
    {"get_ident",               thread_get_ident,
1312
     METH_NOARGS, get_ident_doc},
1313
    {"_count",                  thread__count,
1314 1315
     METH_NOARGS, _count_doc},
    {"stack_size",              (PyCFunction)thread_stack_size,
1316
     METH_VARARGS, stack_size_doc},
1317
    {"_set_sentinel",           thread__set_sentinel,
1318
     METH_NOARGS, _set_sentinel_doc},
1319
    {NULL,                      NULL}           /* sentinel */
1320 1321 1322 1323 1324
};


/* Initialization function */

1325
PyDoc_STRVAR(thread_doc,
1326
"This module provides primitive operations to write multi-threaded programs.\n\
1327
The 'threading' module provides a more convenient interface.");
1328

1329
PyDoc_STRVAR(lock_doc,
1330
"A lock object is a synchronization primitive.  To create a lock,\n\
1331
call threading.Lock().  Methods are:\n\
1332 1333 1334 1335 1336 1337 1338
\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\
1339
will block until another thread unlocks it.  Deadlocks may ensue.");
1340

1341
static struct PyModuleDef threadmodule = {
1342 1343 1344 1345 1346 1347 1348 1349 1350
    PyModuleDef_HEAD_INIT,
    "_thread",
    thread_doc,
    -1,
    thread_methods,
    NULL,
    NULL,
    NULL,
    NULL
1351 1352 1353
};


1354
PyMODINIT_FUNC
1355
PyInit__thread(void)
1356
{
1357 1358 1359
    PyObject *m, *d, *v;
    double time_max;
    double timeout_max;
1360
    PyInterpreterState *interp = _PyInterpreterState_Get();
1361 1362

    /* Initialize types: */
1363 1364
    if (PyType_Ready(&localdummytype) < 0)
        return NULL;
1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376
    if (PyType_Ready(&localtype) < 0)
        return NULL;
    if (PyType_Ready(&Locktype) < 0)
        return NULL;
    if (PyType_Ready(&RLocktype) < 0)
        return NULL;

    /* Create the module and add the functions */
    m = PyModule_Create(&threadmodule);
    if (m == NULL)
        return NULL;

1377
    timeout_max = (_PyTime_t)PY_TIMEOUT_MAX * 1e-6;
1378
    time_max = _PyTime_AsSecondsDouble(_PyTime_MAX);
1379
    timeout_max = Py_MIN(timeout_max, time_max);
1380 1381
    /* Round towards minus infinity */
    timeout_max = floor(timeout_max);
1382 1383 1384

    v = PyFloat_FromDouble(timeout_max);
    if (!v)
1385
        return NULL;
1386
    if (PyModule_AddObject(m, "TIMEOUT_MAX", v) < 0)
1387 1388 1389 1390
        return NULL;

    /* Add a symbolic constant */
    d = PyModule_GetDict(m);
1391 1392
    ThreadError = PyExc_RuntimeError;
    Py_INCREF(ThreadError);
1393

1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406
    PyDict_SetItemString(d, "error", ThreadError);
    Locktype.tp_doc = lock_doc;
    Py_INCREF(&Locktype);
    PyDict_SetItemString(d, "LockType", (PyObject *)&Locktype);

    Py_INCREF(&RLocktype);
    if (PyModule_AddObject(m, "RLock", (PyObject *)&RLocktype) < 0)
        return NULL;

    Py_INCREF(&localtype);
    if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
        return NULL;

1407
    interp->num_threads = 0;
1408

1409 1410 1411 1412
    str_dict = PyUnicode_InternFromString("__dict__");
    if (str_dict == NULL)
        return NULL;

1413 1414 1415
    /* Initialize the C thread library */
    PyThread_init_thread();
    return m;
1416
}