summaryrefslogtreecommitdiffstats
path: root/Modules/_threadmodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/_threadmodule.c')
-rw-r--r--Modules/_threadmodule.c942
1 files changed, 471 insertions, 471 deletions
diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c
index 3d4578a..e218ed6 100644
--- a/Modules/_threadmodule.c
+++ b/Modules/_threadmodule.c
@@ -18,36 +18,36 @@ static PyObject *ThreadError;
/* Lock objects */
typedef struct {
- PyObject_HEAD
- PyThread_type_lock lock_lock;
+ PyObject_HEAD
+ PyThread_type_lock lock_lock;
} lockobject;
static void
lock_dealloc(lockobject *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);
+ 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);
}
static PyObject *
lock_PyThread_acquire_lock(lockobject *self, PyObject *args)
{
- int i = 1;
+ int i = 1;
- if (!PyArg_ParseTuple(args, "|i:acquire", &i))
- return NULL;
+ if (!PyArg_ParseTuple(args, "|i:acquire", &i))
+ return NULL;
- Py_BEGIN_ALLOW_THREADS
- i = PyThread_acquire_lock(self->lock_lock, i);
- Py_END_ALLOW_THREADS
+ Py_BEGIN_ALLOW_THREADS
+ i = PyThread_acquire_lock(self->lock_lock, i);
+ Py_END_ALLOW_THREADS
- return PyBool_FromLong((long)i);
+ return PyBool_FromLong((long)i);
}
PyDoc_STRVAR(acquire_doc,
@@ -64,16 +64,16 @@ The blocking operation is not interruptible.");
static PyObject *
lock_PyThread_release_lock(lockobject *self)
{
- /* 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;
+ /* 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;
}
PyDoc_STRVAR(release_doc,
@@ -87,11 +87,11 @@ but it needn't be locked by the same thread that unlocks it.");
static PyObject *
lock_locked_lock(lockobject *self)
{
- if (PyThread_acquire_lock(self->lock_lock, 0)) {
- PyThread_release_lock(self->lock_lock);
- return PyBool_FromLong(0L);
- }
- return PyBool_FromLong(1L);
+ if (PyThread_acquire_lock(self->lock_lock, 0)) {
+ PyThread_release_lock(self->lock_lock);
+ return PyBool_FromLong(0L);
+ }
+ return PyBool_FromLong(1L);
}
PyDoc_STRVAR(locked_doc,
@@ -101,71 +101,71 @@ PyDoc_STRVAR(locked_doc,
Return whether the lock is in the locked state.");
static PyMethodDef lock_methods[] = {
- {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
- METH_VARARGS, acquire_doc},
- {"acquire", (PyCFunction)lock_PyThread_acquire_lock,
- METH_VARARGS, 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, acquire_doc},
- {"__exit__", (PyCFunction)lock_PyThread_release_lock,
- METH_VARARGS, release_doc},
- {NULL, NULL} /* sentinel */
+ {"acquire_lock", (PyCFunction)lock_PyThread_acquire_lock,
+ METH_VARARGS, acquire_doc},
+ {"acquire", (PyCFunction)lock_PyThread_acquire_lock,
+ METH_VARARGS, 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, acquire_doc},
+ {"__exit__", (PyCFunction)lock_PyThread_release_lock,
+ METH_VARARGS, release_doc},
+ {NULL, NULL} /* sentinel */
};
static PyTypeObject Locktype = {
- PyVarObject_HEAD_INIT(&PyType_Type, 0)
- "_thread.lock", /*tp_name*/
- sizeof(lockobject), /*tp_size*/
- 0, /*tp_itemsize*/
- /* methods */
- (destructor)lock_dealloc, /*tp_dealloc*/
- 0, /*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*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
- 0, /*tp_doc*/
- 0, /*tp_traverse*/
- 0, /*tp_clear*/
- 0, /*tp_richcompare*/
- 0, /*tp_weaklistoffset*/
- 0, /*tp_iter*/
- 0, /*tp_iternext*/
- lock_methods, /*tp_methods*/
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+ "_thread.lock", /*tp_name*/
+ sizeof(lockobject), /*tp_size*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor)lock_dealloc, /*tp_dealloc*/
+ 0, /*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*/
+ Py_TPFLAGS_DEFAULT, /*tp_flags*/
+ 0, /*tp_doc*/
+ 0, /*tp_traverse*/
+ 0, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ lock_methods, /*tp_methods*/
};
static lockobject *
newlockobject(void)
{
- lockobject *self;
- self = PyObject_New(lockobject, &Locktype);
- if (self == NULL)
- return NULL;
- self->lock_lock = PyThread_allocate_lock();
- if (self->lock_lock == NULL) {
- Py_DECREF(self);
- PyErr_SetString(ThreadError, "can't allocate lock");
- return NULL;
- }
- return self;
+ lockobject *self;
+ self = PyObject_New(lockobject, &Locktype);
+ if (self == NULL)
+ return NULL;
+ self->lock_lock = PyThread_allocate_lock();
+ if (self->lock_lock == NULL) {
+ Py_DECREF(self);
+ PyErr_SetString(ThreadError, "can't allocate lock");
+ return NULL;
+ }
+ return self;
}
/* Thread-local objects */
@@ -173,351 +173,351 @@ newlockobject(void)
#include "structmember.h"
typedef struct {
- PyObject_HEAD
- PyObject *key;
- PyObject *args;
- PyObject *kw;
- PyObject *dict;
+ PyObject_HEAD
+ PyObject *key;
+ PyObject *args;
+ PyObject *kw;
+ PyObject *dict;
} localobject;
static PyObject *
local_new(PyTypeObject *type, PyObject *args, PyObject *kw)
{
- localobject *self;
- PyObject *tdict;
-
- if (type->tp_init == PyBaseObject_Type.tp_init
- && ((args && PyObject_IsTrue(args))
- || (kw && PyObject_IsTrue(kw)))) {
- PyErr_SetString(PyExc_TypeError,
- "Initialization arguments are not supported");
- return NULL;
- }
-
- self = (localobject *)type->tp_alloc(type, 0);
- if (self == NULL)
- return NULL;
-
- Py_XINCREF(args);
- self->args = args;
- Py_XINCREF(kw);
- self->kw = kw;
- self->dict = NULL; /* making sure */
- self->key = PyUnicode_FromFormat("thread.local.%p", self);
- if (self->key == NULL)
- goto err;
-
- self->dict = PyDict_New();
- if (self->dict == NULL)
- goto err;
-
- tdict = PyThreadState_GetDict();
- if (tdict == NULL) {
- PyErr_SetString(PyExc_SystemError,
- "Couldn't get thread-state dictionary");
- goto err;
- }
-
- if (PyDict_SetItem(tdict, self->key, self->dict) < 0)
- goto err;
-
- return (PyObject *)self;
+ localobject *self;
+ PyObject *tdict;
+
+ if (type->tp_init == PyBaseObject_Type.tp_init
+ && ((args && PyObject_IsTrue(args))
+ || (kw && PyObject_IsTrue(kw)))) {
+ PyErr_SetString(PyExc_TypeError,
+ "Initialization arguments are not supported");
+ return NULL;
+ }
+
+ self = (localobject *)type->tp_alloc(type, 0);
+ if (self == NULL)
+ return NULL;
+
+ Py_XINCREF(args);
+ self->args = args;
+ Py_XINCREF(kw);
+ self->kw = kw;
+ self->dict = NULL; /* making sure */
+ self->key = PyUnicode_FromFormat("thread.local.%p", self);
+ if (self->key == NULL)
+ goto err;
+
+ self->dict = PyDict_New();
+ if (self->dict == NULL)
+ goto err;
+
+ tdict = PyThreadState_GetDict();
+ if (tdict == NULL) {
+ PyErr_SetString(PyExc_SystemError,
+ "Couldn't get thread-state dictionary");
+ goto err;
+ }
+
+ if (PyDict_SetItem(tdict, self->key, self->dict) < 0)
+ goto err;
+
+ return (PyObject *)self;
err:
- Py_DECREF(self);
- return NULL;
+ Py_DECREF(self);
+ return NULL;
}
static int
local_traverse(localobject *self, visitproc visit, void *arg)
{
- Py_VISIT(self->args);
- Py_VISIT(self->kw);
- Py_VISIT(self->dict);
- return 0;
+ Py_VISIT(self->args);
+ Py_VISIT(self->kw);
+ Py_VISIT(self->dict);
+ return 0;
}
static int
local_clear(localobject *self)
{
- Py_CLEAR(self->args);
- Py_CLEAR(self->kw);
- Py_CLEAR(self->dict);
- return 0;
+ Py_CLEAR(self->args);
+ Py_CLEAR(self->kw);
+ Py_CLEAR(self->dict);
+ return 0;
}
static void
local_dealloc(localobject *self)
{
- PyThreadState *tstate;
- if (self->key
- && (tstate = PyThreadState_Get())
- && tstate->interp) {
- for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
- tstate;
- tstate = PyThreadState_Next(tstate))
- if (tstate->dict &&
- PyDict_GetItem(tstate->dict, self->key))
- PyDict_DelItem(tstate->dict, self->key);
- }
-
- Py_XDECREF(self->key);
- local_clear(self);
- Py_TYPE(self)->tp_free((PyObject*)self);
+ PyThreadState *tstate;
+ if (self->key
+ && (tstate = PyThreadState_Get())
+ && tstate->interp) {
+ for(tstate = PyInterpreterState_ThreadHead(tstate->interp);
+ tstate;
+ tstate = PyThreadState_Next(tstate))
+ if (tstate->dict &&
+ PyDict_GetItem(tstate->dict, self->key))
+ PyDict_DelItem(tstate->dict, self->key);
+ }
+
+ Py_XDECREF(self->key);
+ local_clear(self);
+ Py_TYPE(self)->tp_free((PyObject*)self);
}
static PyObject *
_ldict(localobject *self)
{
- PyObject *tdict, *ldict;
-
- tdict = PyThreadState_GetDict();
- if (tdict == NULL) {
- PyErr_SetString(PyExc_SystemError,
- "Couldn't get thread-state dictionary");
- return NULL;
- }
-
- ldict = PyDict_GetItem(tdict, self->key);
- if (ldict == NULL) {
- ldict = PyDict_New(); /* we own ldict */
-
- if (ldict == NULL)
- return NULL;
- else {
- int i = PyDict_SetItem(tdict, self->key, ldict);
- Py_DECREF(ldict); /* now ldict is borrowed */
- if (i < 0)
- return NULL;
- }
-
- Py_CLEAR(self->dict);
- Py_INCREF(ldict);
- self->dict = ldict; /* still borrowed */
-
- 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
- acces */
- PyDict_DelItem(tdict, self->key);
- return NULL;
- }
-
- }
-
- /* The call to tp_init above may have caused another thread to run.
- Install our ldict again. */
- if (self->dict != ldict) {
- Py_CLEAR(self->dict);
- Py_INCREF(ldict);
- self->dict = ldict;
- }
-
- return ldict;
+ PyObject *tdict, *ldict;
+
+ tdict = PyThreadState_GetDict();
+ if (tdict == NULL) {
+ PyErr_SetString(PyExc_SystemError,
+ "Couldn't get thread-state dictionary");
+ return NULL;
+ }
+
+ ldict = PyDict_GetItem(tdict, self->key);
+ if (ldict == NULL) {
+ ldict = PyDict_New(); /* we own ldict */
+
+ if (ldict == NULL)
+ return NULL;
+ else {
+ int i = PyDict_SetItem(tdict, self->key, ldict);
+ Py_DECREF(ldict); /* now ldict is borrowed */
+ if (i < 0)
+ return NULL;
+ }
+
+ Py_CLEAR(self->dict);
+ Py_INCREF(ldict);
+ self->dict = ldict; /* still borrowed */
+
+ 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
+ acces */
+ PyDict_DelItem(tdict, self->key);
+ return NULL;
+ }
+
+ }
+
+ /* The call to tp_init above may have caused another thread to run.
+ Install our ldict again. */
+ if (self->dict != ldict) {
+ Py_CLEAR(self->dict);
+ Py_INCREF(ldict);
+ self->dict = ldict;
+ }
+
+ return ldict;
}
static int
local_setattro(localobject *self, PyObject *name, PyObject *v)
{
- PyObject *ldict;
-
- ldict = _ldict(self);
- if (ldict == NULL)
- return -1;
+ PyObject *ldict;
- return PyObject_GenericSetAttr((PyObject *)self, name, v);
+ ldict = _ldict(self);
+ if (ldict == NULL)
+ return -1;
+
+ return PyObject_GenericSetAttr((PyObject *)self, name, v);
}
static PyObject *
local_getdict(localobject *self, void *closure)
{
- if (self->dict == NULL) {
- PyErr_SetString(PyExc_AttributeError, "__dict__");
- return NULL;
- }
+ if (self->dict == NULL) {
+ PyErr_SetString(PyExc_AttributeError, "__dict__");
+ return NULL;
+ }
- Py_INCREF(self->dict);
- return self->dict;
+ Py_INCREF(self->dict);
+ return self->dict;
}
static PyGetSetDef local_getset[] = {
- {"__dict__", (getter)local_getdict, (setter)NULL,
- "Local-data dictionary", NULL},
- {NULL} /* Sentinel */
+ {"__dict__", (getter)local_getdict, (setter)NULL,
+ "Local-data dictionary", NULL},
+ {NULL} /* Sentinel */
};
static PyObject *local_getattro(localobject *, PyObject *);
static PyTypeObject localtype = {
- 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,
- /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
- /* tp_doc */ "Thread-local data",
- /* tp_traverse */ (traverseproc)local_traverse,
- /* tp_clear */ (inquiry)local_clear,
- /* tp_richcompare */ 0,
- /* tp_weaklistoffset */ 0,
- /* tp_iter */ 0,
- /* tp_iternext */ 0,
- /* tp_methods */ 0,
- /* tp_members */ 0,
- /* tp_getset */ local_getset,
- /* tp_base */ 0,
- /* tp_dict */ 0, /* internal use */
- /* tp_descr_get */ 0,
- /* tp_descr_set */ 0,
- /* tp_dictoffset */ offsetof(localobject, dict),
- /* 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 */
+ 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,
+ /* tp_flags */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ /* tp_doc */ "Thread-local data",
+ /* tp_traverse */ (traverseproc)local_traverse,
+ /* tp_clear */ (inquiry)local_clear,
+ /* tp_richcompare */ 0,
+ /* tp_weaklistoffset */ 0,
+ /* tp_iter */ 0,
+ /* tp_iternext */ 0,
+ /* tp_methods */ 0,
+ /* tp_members */ 0,
+ /* tp_getset */ local_getset,
+ /* tp_base */ 0,
+ /* tp_dict */ 0, /* internal use */
+ /* tp_descr_get */ 0,
+ /* tp_descr_set */ 0,
+ /* tp_dictoffset */ offsetof(localobject, dict),
+ /* 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 */
};
static PyObject *
local_getattro(localobject *self, PyObject *name)
{
- PyObject *ldict, *value;
+ PyObject *ldict, *value;
- ldict = _ldict(self);
- if (ldict == NULL)
- return NULL;
+ ldict = _ldict(self);
+ if (ldict == NULL)
+ return NULL;
- if (Py_TYPE(self) != &localtype)
- /* use generic lookup for subtypes */
- return PyObject_GenericGetAttr((PyObject *)self, name);
+ if (Py_TYPE(self) != &localtype)
+ /* use generic lookup for subtypes */
+ return PyObject_GenericGetAttr((PyObject *)self, name);
- /* Optimization: just look in dict ourselves */
- value = PyDict_GetItem(ldict, name);
- if (value == NULL)
- /* Fall back on generic to get __class__ and __dict__ */
- return PyObject_GenericGetAttr((PyObject *)self, name);
+ /* Optimization: just look in dict ourselves */
+ value = PyDict_GetItem(ldict, name);
+ if (value == NULL)
+ /* Fall back on generic to get __class__ and __dict__ */
+ return PyObject_GenericGetAttr((PyObject *)self, name);
- Py_INCREF(value);
- return value;
+ Py_INCREF(value);
+ return value;
}
/* Module functions */
struct bootstate {
- PyInterpreterState *interp;
- PyObject *func;
- PyObject *args;
- PyObject *keyw;
- PyThreadState *tstate;
+ PyInterpreterState *interp;
+ PyObject *func;
+ PyObject *args;
+ PyObject *keyw;
+ PyThreadState *tstate;
};
static void
t_bootstrap(void *boot_raw)
{
- 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);
- 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);
- PyThreadState_Clear(tstate);
- PyThreadState_DeleteCurrent();
- PyThread_exit_thread();
+ 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);
+ 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);
+ PyThreadState_Clear(tstate);
+ PyThreadState_DeleteCurrent();
+ PyThread_exit_thread();
}
static PyObject *
thread_PyThread_start_new_thread(PyObject *self, PyObject *fargs)
{
- 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);
+ 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);
}
PyDoc_STRVAR(start_new_doc,
@@ -534,8 +534,8 @@ printed unless the exception is SystemExit.\n");
static PyObject *
thread_PyThread_exit_thread(PyObject *self)
{
- PyErr_SetNone(PyExc_SystemExit);
- return NULL;
+ PyErr_SetNone(PyExc_SystemExit);
+ return NULL;
}
PyDoc_STRVAR(exit_doc,
@@ -548,9 +548,9 @@ thread to exit silently unless the exception is caught.");
static PyObject *
thread_PyThread_interrupt_main(PyObject * self)
{
- PyErr_SetInterrupt();
- Py_INCREF(Py_None);
- return Py_None;
+ PyErr_SetInterrupt();
+ Py_INCREF(Py_None);
+ return Py_None;
}
PyDoc_STRVAR(interrupt_doc,
@@ -564,11 +564,11 @@ A subthread can use this function to interrupt the main thread."
static PyObject *
thread_PyThread_exit_prog(PyObject *self, PyObject *args)
{
- int sts;
- if (!PyArg_ParseTuple(args, "i:exit_prog", &sts))
- return NULL;
- Py_Exit(sts); /* Calls PyThread_exit_prog(sts) or _PyThread_exit_prog(sts) */
- for (;;) { } /* Should not be reached */
+ int sts;
+ if (!PyArg_ParseTuple(args, "i:exit_prog", &sts))
+ return NULL;
+ Py_Exit(sts); /* Calls PyThread_exit_prog(sts) or _PyThread_exit_prog(sts) */
+ for (;;) { } /* Should not be reached */
}
#endif
@@ -577,7 +577,7 @@ static lockobject *newlockobject(void);
static PyObject *
thread_PyThread_allocate_lock(PyObject *self)
{
- return (PyObject *) newlockobject();
+ return (PyObject *) newlockobject();
}
PyDoc_STRVAR(allocate_doc,
@@ -589,13 +589,13 @@ Create a new lock object. See LockType.__doc__ for information about locks.");
static PyObject *
thread_get_ident(PyObject *self)
{
- long ident;
- ident = PyThread_get_thread_ident();
- if (ident == -1) {
- PyErr_SetString(ThreadError, "no current thread ident");
- return NULL;
- }
- return PyLong_FromLong(ident);
+ long ident;
+ ident = PyThread_get_thread_ident();
+ if (ident == -1) {
+ PyErr_SetString(ThreadError, "no current thread ident");
+ return NULL;
+ }
+ return PyLong_FromLong(ident);
}
PyDoc_STRVAR(get_ident_doc,
@@ -612,35 +612,35 @@ A thread's identity may be reused for another thread after it exits.");
static PyObject *
thread_stack_size(PyObject *self, PyObject *args)
{
- size_t old_size;
- Py_ssize_t new_size = 0;
- int rc;
-
- if (!PyArg_ParseTuple(args, "|n:stack_size", &new_size))
- return NULL;
-
- if (new_size < 0) {
- PyErr_SetString(PyExc_ValueError,
- "size must be 0 or a positive value");
- return NULL;
- }
-
- old_size = PyThread_get_stacksize();
-
- rc = PyThread_set_stacksize((size_t) new_size);
- if (rc == -1) {
- PyErr_Format(PyExc_ValueError,
- "size not valid: %zd bytes",
- new_size);
- return NULL;
- }
- if (rc == -2) {
- PyErr_SetString(ThreadError,
- "setting stack size not supported");
- return NULL;
- }
-
- return PyLong_FromSsize_t((Py_ssize_t) old_size);
+ 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);
}
PyDoc_STRVAR(stack_size_doc,
@@ -664,32 +664,32 @@ requiring allocation in multiples of the system memory page size\n\
the suggested approach in the absence of more specific information).");
static PyMethodDef thread_methods[] = {
- {"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},
- {"stack_size", (PyCFunction)thread_stack_size,
- METH_VARARGS,
- stack_size_doc},
+ {"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},
+ {"stack_size", (PyCFunction)thread_stack_size,
+ METH_VARARGS,
+ stack_size_doc},
#ifndef NO_EXIT_PROG
- {"exit_prog", (PyCFunction)thread_PyThread_exit_prog,
- METH_VARARGS},
+ {"exit_prog", (PyCFunction)thread_PyThread_exit_prog,
+ METH_VARARGS},
#endif
- {NULL, NULL} /* sentinel */
+ {NULL, NULL} /* sentinel */
};
@@ -712,47 +712,47 @@ 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.");
static struct PyModuleDef threadmodule = {
- PyModuleDef_HEAD_INIT,
- "_thread",
- thread_doc,
- -1,
- thread_methods,
- NULL,
- NULL,
- NULL,
- NULL
+ PyModuleDef_HEAD_INIT,
+ "_thread",
+ thread_doc,
+ -1,
+ thread_methods,
+ NULL,
+ NULL,
+ NULL,
+ NULL
};
PyMODINIT_FUNC
PyInit__thread(void)
{
- PyObject *m, *d;
-
- /* Initialize types: */
- if (PyType_Ready(&localtype) < 0)
- return NULL;
- if (PyType_Ready(&Locktype) < 0)
- return NULL;
-
- /* Create the module and add the functions */
- m = PyModule_Create(&threadmodule);
- if (m == NULL)
- 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(&localtype);
- if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
- return NULL;
-
- /* Initialize the C thread library */
- PyThread_init_thread();
- return m;
+ PyObject *m, *d;
+
+ /* Initialize types: */
+ if (PyType_Ready(&localtype) < 0)
+ return NULL;
+ if (PyType_Ready(&Locktype) < 0)
+ return NULL;
+
+ /* Create the module and add the functions */
+ m = PyModule_Create(&threadmodule);
+ if (m == NULL)
+ 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(&localtype);
+ if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
+ return NULL;
+
+ /* Initialize the C thread library */
+ PyThread_init_thread();
+ return m;
}