Back to index

python3.2  3.2.2
Classes | Functions | Variables
_threadmodule.c File Reference
#include "Python.h"
#include "structmember.h"
#include "pythread.h"

Go to the source code of this file.

Classes

struct  lockobject
struct  rlockobject
struct  localdummyobject
struct  localobject
struct  bootstate

Functions

static void lock_dealloc (lockobject *self)
static PyLockStatus acquire_timed (PyThread_type_lock lock, PY_TIMEOUT_T microseconds)
static PyObjectlock_PyThread_acquire_lock (lockobject *self, PyObject *args, PyObject *kwds)
 PyDoc_STRVAR (acquire_doc,"acquire([wait]) -> None or bool\n\ (acquire_lock() is an obsolete synonym)\n\ \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\ the lock, and return None once the lock is acquired.\n\ With an argument, this will only block if the argument is true,\n\ and the return value reflects whether the lock is acquired.\n\ The blocking operation is interruptible.")
static PyObjectlock_PyThread_release_lock (lockobject *self)
 PyDoc_STRVAR (release_doc,"release()\n\ (release_lock() is an obsolete synonym)\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\ but it needn't be locked by the same thread that unlocks it.")
static PyObjectlock_locked_lock (lockobject *self)
 PyDoc_STRVAR (locked_doc,"locked() -> bool\n\ (locked_lock() is an obsolete synonym)\n\ \n\ Return whether the lock is in the locked state.")
static void rlock_dealloc (rlockobject *self)
static PyObjectrlock_acquire (rlockobject *self, PyObject *args, PyObject *kwds)
 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\ (note: the blocking operation is interruptible.)\n\ \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 PyObjectrlock_release (rlockobject *self)
 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 PyObjectrlock_acquire_restore (rlockobject *self, PyObject *arg)
 PyDoc_STRVAR (rlock_acquire_restore_doc,"_acquire_restore(state) -> None\n\ \n\ For internal use by `threading.Condition`.")
static PyObjectrlock_release_save (rlockobject *self)
 PyDoc_STRVAR (rlock_release_save_doc,"_release_save() -> tuple\n\ \n\ For internal use by `threading.Condition`.")
static PyObjectrlock_is_owned (rlockobject *self)
 PyDoc_STRVAR (rlock_is_owned_doc,"_is_owned() -> bool\n\ \n\ For internal use by `threading.Condition`.")
static PyObjectrlock_new (PyTypeObject *type, PyObject *args, PyObject *kwds)
static PyObjectrlock_repr (rlockobject *self)
static lockobjectnewlockobject (void)
static void localdummy_dealloc (localdummyobject *self)
static PyObject_ldict (localobject *self)
static PyObject_localdummy_destroyed (PyObject *meth_self, PyObject *dummyweakref)
static PyObject_local_create_dummy (localobject *self)
static PyObjectlocal_new (PyTypeObject *type, PyObject *args, PyObject *kw)
static int local_traverse (localobject *self, visitproc visit, void *arg)
static int local_clear (localobject *self)
static void local_dealloc (localobject *self)
static int local_setattro (localobject *self, PyObject *name, PyObject *v)
static PyObjectlocal_getattro (localobject *, PyObject *)
static void t_bootstrap (void *boot_raw)
static PyObjectthread_PyThread_start_new_thread (PyObject *self, PyObject *fargs)
 PyDoc_STRVAR (start_new_doc,"start_new_thread(function, args[, kwargs])\n\ (start_new() is an obsolete synonym)\n\ \n\ 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\ printed unless the exception is SystemExit.\n")
static PyObjectthread_PyThread_exit_thread (PyObject *self)
 PyDoc_STRVAR (exit_doc,"exit()\n\ (exit_thread() is an obsolete synonym)\n\ \n\ This is synonymous to ``raise SystemExit''. It will cause the current\n\ thread to exit silently unless the exception is caught.")
static PyObjectthread_PyThread_interrupt_main (PyObject *self)
 PyDoc_STRVAR (interrupt_doc,"interrupt_main()\n\ \n\ Raise a KeyboardInterrupt in the main thread.\n\ A subthread can use this function to interrupt the main thread.")
static PyObjectthread_PyThread_allocate_lock (PyObject *self)
 PyDoc_STRVAR (allocate_doc,"allocate_lock() -> lock object\n\ (allocate() is an obsolete synonym)\n\ \n\ Create a new lock object. See help(LockType) for information about locks.")
static PyObjectthread_get_ident (PyObject *self)
 PyDoc_STRVAR (get_ident_doc,"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\ A thread's identity may be reused for another thread after it exits.")
static PyObjectthread__count (PyObject *self)
 PyDoc_STRVAR (_count_doc,"_count() -> integer\n\ \n\ \ Return the number of currently running Python threads, excluding \n\ 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.")
static PyObjectthread_stack_size (PyObject *self, PyObject *args)
 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).")
 PyDoc_STRVAR (thread_doc,"This module provides primitive operations to write multi-threaded programs.\n\ The 'threading' module provides a more convenient interface.")
 PyDoc_STRVAR (lock_doc,"A lock object is a synchronization primitive. To create a lock,\n\ call the PyThread_allocate_lock() function. Methods are:\n\ \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\ will block until another thread unlocks it. Deadlocks may ensue.")
PyMODINIT_FUNC PyInit__thread (void)

Variables

static PyObjectThreadError
static long nb_threads = 0
static PyObjectstr_dict
static PyMethodDef lock_methods []
static PyTypeObject Locktype
static PyMethodDef rlock_methods []
static PyTypeObject RLocktype
static PyTypeObject localdummytype
static PyTypeObject localtype
static PyMethodDef thread_methods []
static struct PyModuleDef

Class Documentation

struct lockobject

Definition at line 22 of file _threadmodule.c.

Collaboration diagram for lockobject:
Class Members
PyObject * in_weakreflist
PyObject_HEAD PyThread_type_lock lock_lock
struct rlockobject

Definition at line 244 of file _threadmodule.c.

Collaboration diagram for rlockobject:
Class Members
PyObject * in_weakreflist
unsigned long rlock_count
PyObject_HEAD PyThread_type_lock rlock_lock
long rlock_owner
struct localdummyobject

Definition at line 596 of file _threadmodule.c.

Collaboration diagram for localdummyobject:
Class Members
PyObject_HEAD PyObject * localdict
PyObject * weakreflist
struct localobject

Definition at line 639 of file _threadmodule.c.

Collaboration diagram for localobject:
Class Members
PyObject * args
PyObject * dummies
PyObject_HEAD PyObject * key
PyObject * kw
PyObject * weakreflist
PyObject * wr_callback
struct bootstate

Definition at line 970 of file _threadmodule.c.

Collaboration diagram for bootstate:
Class Members
PyObject * args
PyObject * func
PyInterpreterState * interp
PyObject * keyw
PyThreadState * tstate

Function Documentation

static PyObject * _ldict ( localobject self) [static]

Definition at line 804 of file _threadmodule.c.

{
    PyObject *tdict, *ldict, *dummy;

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

    dummy = PyDict_GetItem(tdict, self->key);
    if (dummy == NULL) {
        ldict = _local_create_dummy(self);
        if (ldict == NULL)
            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
               access */
            PyDict_DelItem(tdict, self->key);
            return NULL;
        }
    }
    else {
        assert(Py_TYPE(dummy) == &localdummytype);
        ldict = ((localdummyobject *) dummy)->localdict;
    }

    return ldict;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PyObject* _local_create_dummy ( localobject self) [static]

Definition at line 658 of file _threadmodule.c.

{
    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);

    Py_DECREF(ldict);
    return ldict;

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

Here is the call graph for this function:

Here is the caller graph for this function:

static PyObject * _localdummy_destroyed ( PyObject meth_self,
PyObject dummyweakref 
) [static]

Definition at line 942 of file _threadmodule.c.

{
    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;
        ldict = PyDict_GetItem(self->dummies, dummyweakref);
        if (ldict != NULL) {
            PyDict_DelItem(self->dummies, dummyweakref);
        }
        if (PyErr_Occurred())
            PyErr_WriteUnraisable(obj);
    }
    Py_DECREF(obj);
    Py_RETURN_NONE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PyLockStatus acquire_timed ( PyThread_type_lock  lock,
PY_TIMEOUT_T  microseconds 
) [static]

Definition at line 50 of file _threadmodule.c.

{
    PyLockStatus r;
    _PyTime_timeval curtime;
    _PyTime_timeval endtime;

    if (microseconds > 0) {
        _PyTime_gettimeofday(&endtime);
        endtime.tv_sec += microseconds / (1000 * 1000);
        endtime.tv_usec += microseconds % (1000 * 1000);
    }


    do {
        Py_BEGIN_ALLOW_THREADS
        r = PyThread_acquire_lock_timed(lock, microseconds, 1);
        Py_END_ALLOW_THREADS

        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.  */
            if (microseconds >= 0) {
                _PyTime_gettimeofday(&curtime);
                microseconds = ((endtime.tv_sec - curtime.tv_sec) * 1000000 +
                                (endtime.tv_usec - curtime.tv_usec));

                /* Check for negative values, since those mean block forever.
                 */
                if (microseconds <= 0) {
                    r = PY_LOCK_FAILURE;
                }
            }
        }
    } while (r == PY_LOCK_INTR);  /* Retry if we were interrupted. */

    return r;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int local_clear ( localobject self) [static]

Definition at line 766 of file _threadmodule.c.

{
    PyThreadState *tstate;
    Py_CLEAR(self->args);
    Py_CLEAR(self->kw);
    Py_CLEAR(self->dummies);
    Py_CLEAR(self->wr_callback);
    /* Remove all strong references to dummies from the thread states */
    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);
    }
    return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void local_dealloc ( localobject self) [static]

Definition at line 788 of file _threadmodule.c.

{
    /* 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);

    local_clear(self);
    Py_XDECREF(self->key);
    Py_TYPE(self)->tp_free((PyObject*)self);
}

Here is the call graph for this function:

static PyObject * local_getattro ( localobject self,
PyObject name 
) [static]

Definition at line 909 of file _threadmodule.c.

{
    PyObject *ldict, *value;
    int r;

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

    r = PyObject_RichCompareBool(name, str_dict, Py_EQ);
    if (r == 1) {
        Py_INCREF(ldict);
        return ldict;
    }
    if (r == -1)
        return NULL;

    if (Py_TYPE(self) != &localtype)
        /* use generic lookup for subtypes */
        return _PyObject_GenericGetAttrWithDict((PyObject *)self, name, ldict);

    /* 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_GenericGetAttrWithDict((PyObject *)self, name, ldict);

    Py_INCREF(value);
    return value;
}

Here is the call graph for this function:

static PyObject* local_new ( PyTypeObject type,
PyObject args,
PyObject kw 
) [static]

Definition at line 704 of file _threadmodule.c.

{
    localobject *self;
    PyObject *wr;
    static PyMethodDef wr_callback_def = {
        "_localdummy_destroyed", (PyCFunction) _localdummy_destroyed, METH_O
    };

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

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

    /* 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;
    self->wr_callback = PyCFunction_New(&wr_callback_def, wr);
    Py_DECREF(wr);
    if (self->wr_callback == NULL)
        goto err;

    if (_local_create_dummy(self) == NULL)
        goto err;

    return (PyObject *)self;

  err:
    Py_DECREF(self);
    return NULL;
}

Here is the call graph for this function:

static int local_setattro ( localobject self,
PyObject name,
PyObject v 
) [static]

Definition at line 840 of file _threadmodule.c.

{
    PyObject *ldict;
    int r;

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

    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;

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

Here is the call graph for this function:

static int local_traverse ( localobject self,
visitproc  visit,
void arg 
) [static]

Definition at line 757 of file _threadmodule.c.

{
    Py_VISIT(self->args);
    Py_VISIT(self->kw);
    Py_VISIT(self->dummies);
    return 0;
}
static void localdummy_dealloc ( localdummyobject self) [static]

Definition at line 603 of file _threadmodule.c.

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

Here is the call graph for this function:

static void lock_dealloc ( lockobject self) [static]

Definition at line 29 of file _threadmodule.c.

{
    if (self->in_weakreflist != NULL)
        PyObject_ClearWeakRefs((PyObject *) self);
    if (self->lock_lock != NULL) {
        /* Unlock the lock so it's safe to free it */
        PyThread_acquire_lock(self->lock_lock, 0);
        PyThread_release_lock(self->lock_lock);

        PyThread_free_lock(self->lock_lock);
    }
    PyObject_Del(self);
}

Here is the call graph for this function:

static PyObject* lock_locked_lock ( lockobject self) [static]

Definition at line 175 of file _threadmodule.c.

Here is the call graph for this function:

static PyObject* lock_PyThread_acquire_lock ( lockobject self,
PyObject args,
PyObject kwds 
) [static]

Definition at line 96 of file _threadmodule.c.

{
    char *kwlist[] = {"blocking", "timeout", NULL};
    int blocking = 1;
    double timeout = -1;
    PY_TIMEOUT_T microseconds;
    PyLockStatus r;

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|id:acquire", kwlist,
                                     &blocking, &timeout))
        return NULL;

    if (!blocking && timeout != -1) {
        PyErr_SetString(PyExc_ValueError, "can't specify a timeout "
                        "for a non-blocking call");
        return NULL;
    }
    if (timeout < 0 && timeout != -1) {
        PyErr_SetString(PyExc_ValueError, "timeout value must be "
                        "strictly positive");
        return NULL;
    }
    if (!blocking)
        microseconds = 0;
    else if (timeout == -1)
        microseconds = -1;
    else {
        timeout *= 1e6;
        if (timeout >= (double) PY_TIMEOUT_MAX) {
            PyErr_SetString(PyExc_OverflowError,
                            "timeout value is too large");
            return NULL;
        }
        microseconds = (PY_TIMEOUT_T) timeout;
    }

    r = acquire_timed(self->lock_lock, microseconds);
    if (r == PY_LOCK_INTR) {
        return NULL;
    }

    return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
}

Here is the call graph for this function:

static PyObject* lock_PyThread_release_lock ( lockobject self) [static]

Definition at line 152 of file _threadmodule.c.

{
    /* Sanity check: the lock must be locked */
    if (PyThread_acquire_lock(self->lock_lock, 0)) {
        PyThread_release_lock(self->lock_lock);
        PyErr_SetString(ThreadError, "release unlocked lock");
        return NULL;
    }

    PyThread_release_lock(self->lock_lock);
    Py_INCREF(Py_None);
    return Py_None;
}

Here is the call graph for this function:

static lockobject * newlockobject ( void  ) [static]

Definition at line 537 of file _threadmodule.c.

{
    lockobject *self;
    self = PyObject_New(lockobject, &Locktype);
    if (self == NULL)
        return NULL;
    self->lock_lock = PyThread_allocate_lock();
    self->in_weakreflist = NULL;
    if (self->lock_lock == NULL) {
        Py_DECREF(self);
        PyErr_SetString(ThreadError, "can't allocate lock");
        return NULL;
    }
    return self;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PyDoc_STRVAR ( acquire_doc  ,
"acquire([wait]) -> None or bool\n\(acquire_lock() is an obsolete synonym)\n\\n\Lock the lock. Without  argument,
this blocks if the lock is already\n\  lockedeven by the same thread,
waiting for another thread to release\n\the  lock,
and return None once the lock is acquired.\n\With an  argument,
this will only block if the argument is  true,
\n\and the return value reflects whether the lock is acquired.\n\The blocking operation is interruptible."   
)
PyDoc_STRVAR ( release_doc  ,
"release()\n\(release_lock() is an obsolete synonym)\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\but it needn't be locked by the same thread that unlocks it."   
)
PyDoc_STRVAR ( locked_doc  ,
"locked() -> bool\n\(locked_lock() is an obsolete synonym)\n\\n\Return whether the lock is in the locked state."   
)
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\(note:the blocking operation is interruptible.)\n\\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."   
)
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."   
)
PyDoc_STRVAR ( rlock_acquire_restore_doc  ,
"_acquire_restore(state) -> None\n\\n\For internal use by `threading.Condition`."   
)
PyDoc_STRVAR ( rlock_release_save_doc  ,
"_release_save() -> tuple\n\\n\For internal use by `threading.Condition`."   
)
PyDoc_STRVAR ( rlock_is_owned_doc  ,
"_is_owned() -> bool\n\\n\For internal use by `threading.Condition`."   
)
PyDoc_STRVAR ( start_new_doc  ,
"start_new_thread(function, args[, kwargs])\n\(start_new() is an obsolete synonym)\n\\n\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\printed unless the exception is SystemExit.\n  
)
PyDoc_STRVAR ( exit_doc  ,
"exit()\n\(exit_thread() is an obsolete synonym)\n\\n\This is synonymous to ``raise SystemExit''. It will cause the current\n\thread to exit silently unless the exception is caught."   
)
PyDoc_STRVAR ( interrupt_doc  ,
"interrupt_main()\n\\n\Raise a KeyboardInterrupt in the main thread.\n\A subthread can use this function to interrupt the main thread."   
)
PyDoc_STRVAR ( allocate_doc  ,
"allocate_lock() -> lock object\n\(allocate() is an obsolete synonym)\n\\n\Create a new lock object. See help(LockType) for information about locks."   
)
PyDoc_STRVAR ( get_ident_doc  ,
"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\A thread's identity may be reused for another thread after it exits."   
)
PyDoc_STRVAR ( _count_doc  ,
"_count() -> integer\n\\n\\Return the number of currently running Python  threads,
excluding\n\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."   
)
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)."   
)
PyDoc_STRVAR ( thread_doc  ,
"This module provides primitive operations to write multi-threaded programs.\n\The 'threading' module provides a more convenient interface."   
)
PyDoc_STRVAR ( lock_doc  ,
"A lock object is a synchronization primitive. To create a  lock,
\n\call the PyThread_allocate_lock() function.Methods are:\n\\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\will block until another thread unlocks it.Deadlocks may ensue."   
)

Definition at line 1283 of file _threadmodule.c.

{
    PyObject *m, *d, *timeout_max;

    /* Initialize types: */
    if (PyType_Ready(&localdummytype) < 0)
        return NULL;
    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;

    timeout_max = PyFloat_FromDouble(PY_TIMEOUT_MAX / 1000000);
    if (!timeout_max)
        return NULL;
    if (PyModule_AddObject(m, "TIMEOUT_MAX", timeout_max) < 0)
        return NULL;

    /* Add a symbolic constant */
    d = PyModule_GetDict(m);
    ThreadError = PyErr_NewException("_thread.error", NULL, NULL);
    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;

    nb_threads = 0;

    str_dict = PyUnicode_InternFromString("__dict__");
    if (str_dict == NULL)
        return NULL;

    /* Initialize the C thread library */
    PyThread_init_thread();
    return m;
}

Here is the call graph for this function:

static PyObject* rlock_acquire ( rlockobject self,
PyObject args,
PyObject kwds 
) [static]

Definition at line 267 of file _threadmodule.c.

{
    char *kwlist[] = {"blocking", "timeout", NULL};
    int blocking = 1;
    double timeout = -1;
    PY_TIMEOUT_T microseconds;
    long tid;
    PyLockStatus r = PY_LOCK_ACQUIRED;

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|id:acquire", kwlist,
                                     &blocking, &timeout))
        return NULL;

    if (!blocking && timeout != -1) {
        PyErr_SetString(PyExc_ValueError, "can't specify a timeout "
                        "for a non-blocking call");
        return NULL;
    }
    if (timeout < 0 && timeout != -1) {
        PyErr_SetString(PyExc_ValueError, "timeout value must be "
                        "strictly positive");
        return NULL;
    }
    if (!blocking)
        microseconds = 0;
    else if (timeout == -1)
        microseconds = -1;
    else {
        timeout *= 1e6;
        if (timeout >= (double) PY_TIMEOUT_MAX) {
            PyErr_SetString(PyExc_OverflowError,
                            "timeout value is too large");
            return NULL;
        }
        microseconds = (PY_TIMEOUT_T) timeout;
    }

    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;
    }

    if (self->rlock_count > 0 ||
        !PyThread_acquire_lock(self->rlock_lock, 0)) {
        if (microseconds == 0) {
            Py_RETURN_FALSE;
        }
        r = acquire_timed(self->rlock_lock, microseconds);
    }
    if (r == PY_LOCK_ACQUIRED) {
        assert(self->rlock_count == 0);
        self->rlock_owner = tid;
        self->rlock_count = 1;
    }
    else if (r == PY_LOCK_INTR) {
        return NULL;
    }

    return PyBool_FromLong(r == PY_LOCK_ACQUIRED);
}

Here is the call graph for this function:

static PyObject* rlock_acquire_restore ( rlockobject self,
PyObject arg 
) [static]

Definition at line 381 of file _threadmodule.c.

{
    long owner;
    unsigned long count;
    int r = 1;

    if (!PyArg_ParseTuple(arg, "kl:_acquire_restore", &count, &owner))
        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;
}

Here is the call graph for this function:

static void rlock_dealloc ( rlockobject self) [static]

Definition at line 253 of file _threadmodule.c.

{
    assert(self->rlock_lock);
    if (self->in_weakreflist != NULL)
        PyObject_ClearWeakRefs((PyObject *) self);
    /* Unlock the lock so it's safe to free it */
    if (self->rlock_count > 0)
        PyThread_release_lock(self->rlock_lock);

    PyThread_free_lock(self->rlock_lock);
    Py_TYPE(self)->tp_free(self);
}

Here is the call graph for this function:

static PyObject* rlock_is_owned ( rlockobject self) [static]

Definition at line 431 of file _threadmodule.c.

{
    long tid = PyThread_get_thread_ident();

    if (self->rlock_count > 0 && self->rlock_owner == tid) {
        Py_RETURN_TRUE;
    }
    Py_RETURN_FALSE;
}

Here is the call graph for this function:

static PyObject* rlock_new ( PyTypeObject type,
PyObject args,
PyObject kwds 
) [static]

Definition at line 447 of file _threadmodule.c.

{
    rlockobject *self;

    self = (rlockobject *) type->tp_alloc(type, 0);
    if (self != NULL) {
        self->rlock_lock = PyThread_allocate_lock();
        if (self->rlock_lock == NULL) {
            type->tp_free(self);
            PyErr_SetString(ThreadError, "can't allocate lock");
            return NULL;
        }
        self->in_weakreflist = NULL;
        self->rlock_owner = 0;
        self->rlock_count = 0;
    }

    return (PyObject *) self;
}

Here is the call graph for this function:

static PyObject* rlock_release ( rlockobject self) [static]

Definition at line 352 of file _threadmodule.c.

{
    long tid = PyThread_get_thread_ident();

    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;
}

Here is the call graph for this function:

static PyObject* rlock_release_save ( rlockobject self) [static]

Definition at line 411 of file _threadmodule.c.

{
    long owner;
    unsigned long count;

    owner = self->rlock_owner;
    count = self->rlock_count;
    self->rlock_count = 0;
    self->rlock_owner = 0;
    PyThread_release_lock(self->rlock_lock);
    return Py_BuildValue("kl", count, owner);
}

Here is the call graph for this function:

static PyObject* rlock_repr ( rlockobject self) [static]

Definition at line 468 of file _threadmodule.c.

{
    return PyUnicode_FromFormat("<%s owner=%ld count=%lu>",
        Py_TYPE(self)->tp_name, self->rlock_owner, self->rlock_count);
}
static void t_bootstrap ( void boot_raw) [static]

Definition at line 979 of file _threadmodule.c.

{
    struct bootstate *boot = (struct bootstate *) boot_raw;
    PyThreadState *tstate;
    PyObject *res;

    tstate = boot->tstate;
    tstate->thread_id = PyThread_get_thread_ident();
    _PyThreadState_Init(tstate);
    PyEval_AcquireThread(tstate);
    nb_threads++;
    res = PyEval_CallObjectWithKeywords(
        boot->func, boot->args, boot->keyw);
    if (res == NULL) {
        if (PyErr_ExceptionMatches(PyExc_SystemExit))
            PyErr_Clear();
        else {
            PyObject *file;
            PySys_WriteStderr(
                "Unhandled exception in thread started by ");
            file = PySys_GetObject("stderr");
            if (file != NULL && file != Py_None)
                PyFile_WriteObject(boot->func, file, 0);
            else
                PyObject_Print(boot->func, stderr, 0);
            PySys_WriteStderr("\n");
            PyErr_PrintEx(0);
        }
    }
    else
        Py_DECREF(res);
    Py_DECREF(boot->func);
    Py_DECREF(boot->args);
    Py_XDECREF(boot->keyw);
    PyMem_DEL(boot_raw);
    nb_threads--;
    PyThreadState_Clear(tstate);
    PyThreadState_DeleteCurrent();
    PyThread_exit_thread();
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PyObject* thread__count ( PyObject self) [static]

Definition at line 1152 of file _threadmodule.c.

Here is the call graph for this function:

static PyObject* thread_get_ident ( PyObject self) [static]

Definition at line 1129 of file _threadmodule.c.

{
    long ident;
    ident = PyThread_get_thread_ident();
    if (ident == -1) {
        PyErr_SetString(ThreadError, "no current thread ident");
        return NULL;
    }
    return PyLong_FromLong(ident);
}

Here is the call graph for this function:

static PyObject* thread_PyThread_allocate_lock ( PyObject self) [static]

Definition at line 1117 of file _threadmodule.c.

{
    return (PyObject *) newlockobject();
}

Here is the call graph for this function:

static PyObject* thread_PyThread_exit_thread ( PyObject self) [static]

Definition at line 1086 of file _threadmodule.c.

{
    PyErr_SetNone(PyExc_SystemExit);
    return NULL;
}

Here is the call graph for this function:

static PyObject* thread_PyThread_interrupt_main ( PyObject self) [static]

Definition at line 1100 of file _threadmodule.c.

Here is the call graph for this function:

static PyObject* thread_PyThread_start_new_thread ( PyObject self,
PyObject fargs 
) [static]

Definition at line 1021 of file _threadmodule.c.

{
    PyObject *func, *args, *keyw = NULL;
    struct bootstate *boot;
    long ident;

    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();
    boot->interp = PyThreadState_GET()->interp;
    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);
    if (ident == -1) {
        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;
    }
    return PyLong_FromLong(ident);
}

Here is the call graph for this function:

static PyObject* thread_stack_size ( PyObject self,
PyObject args 
) [static]

Definition at line 1170 of file _threadmodule.c.

{
    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);
}

Here is the call graph for this function:


Variable Documentation

Initial value:
 {
    PyVarObject_HEAD_INIT(NULL, 0)
     "_thread._localdummy",
     sizeof(localdummyobject),
     0,
     (destructor)localdummy_dealloc,
     0,
     0,
     0,
     0,
     0,
     0,
     0,
     0,
     0,
     0,
     0,
     0,
     0,
     0,
     Py_TPFLAGS_DEFAULT,
     "Thread-local dummy",
     0,
     0,
     0,
     offsetof(localdummyobject, weakreflist)
}

Definition at line 610 of file _threadmodule.c.

Definition at line 864 of file _threadmodule.c.

Initial value:
 {
    {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
     METH_VARARGS | METH_KEYWORDS, acquire_doc},
    {"acquire",      (PyCFunction)lock_PyThread_acquire_lock,
     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},
    {"__enter__",    (PyCFunction)lock_PyThread_acquire_lock,
     METH_VARARGS | METH_KEYWORDS, acquire_doc},
    {"__exit__",    (PyCFunction)lock_PyThread_release_lock,
     METH_VARARGS, release_doc},
    {NULL,           NULL}              
}

Definition at line 190 of file _threadmodule.c.

Definition at line 210 of file _threadmodule.c.

long nb_threads = 0 [static]

Definition at line 17 of file _threadmodule.c.

struct PyModuleDef [static]
Initial value:
 {
    PyModuleDef_HEAD_INIT,
    "_thread",
    thread_doc,
    -1,
    thread_methods,
    NULL,
    NULL,
    NULL,
    NULL
}

Definition at line 1269 of file _threadmodule.c.

Initial value:
 {
    {"acquire",      (PyCFunction)rlock_acquire,
     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,
     METH_O, rlock_acquire_restore_doc},
    {"_release_save", (PyCFunction)rlock_release_save,
     METH_NOARGS, rlock_release_save_doc},
    {"__enter__",    (PyCFunction)rlock_acquire,
     METH_VARARGS | METH_KEYWORDS, rlock_acquire_doc},
    {"__exit__",    (PyCFunction)rlock_release,
     METH_VARARGS, rlock_release_doc},
    {NULL,           NULL}              
}

Definition at line 475 of file _threadmodule.c.

Definition at line 494 of file _threadmodule.c.

PyObject* str_dict [static]

Definition at line 18 of file _threadmodule.c.

Initial value:
 {
    {"start_new_thread",        (PyCFunction)thread_PyThread_start_new_thread,
                            METH_VARARGS,
                            start_new_doc},
    {"start_new",               (PyCFunction)thread_PyThread_start_new_thread,
                            METH_VARARGS,
                            start_new_doc},
    {"allocate_lock",           (PyCFunction)thread_PyThread_allocate_lock,
     METH_NOARGS, allocate_doc},
    {"allocate",                (PyCFunction)thread_PyThread_allocate_lock,
     METH_NOARGS, allocate_doc},
    {"exit_thread",             (PyCFunction)thread_PyThread_exit_thread,
     METH_NOARGS, exit_doc},
    {"exit",                    (PyCFunction)thread_PyThread_exit_thread,
     METH_NOARGS, exit_doc},
    {"interrupt_main",          (PyCFunction)thread_PyThread_interrupt_main,
     METH_NOARGS, interrupt_doc},
    {"get_ident",               (PyCFunction)thread_get_ident,
     METH_NOARGS, get_ident_doc},
    {"_count",                  (PyCFunction)thread__count,
     METH_NOARGS, _count_doc},
    {"stack_size",              (PyCFunction)thread_stack_size,
                            METH_VARARGS,
                            stack_size_doc},
    {NULL,                      NULL}           
}

Definition at line 1223 of file _threadmodule.c.

PyObject* ThreadError [static]

Definition at line 16 of file _threadmodule.c.