summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorKristján Valur Jónsson <kristjan@ccpgames.com>2009-01-09 21:35:16 (GMT)
committerKristján Valur Jónsson <kristjan@ccpgames.com>2009-01-09 21:35:16 (GMT)
commit0e2d8c36e3b52b7ff9d2926d1c2ad4be9df84710 (patch)
treecdfe6ca9439994206d86af13cc247383affeec8a /Modules
parent0e91938e5851173821f917bf19157dde5f946c09 (diff)
downloadcpython-0e2d8c36e3b52b7ff9d2926d1c2ad4be9df84710.zip
cpython-0e2d8c36e3b52b7ff9d2926d1c2ad4be9df84710.tar.gz
cpython-0e2d8c36e3b52b7ff9d2926d1c2ad4be9df84710.tar.bz2
Issue 4293: Make Py_AddPendingCall() thread safe
Add test cases and documentation
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_testcapimodule.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 665d375..1475f72 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -837,6 +837,43 @@ test_thread_state(PyObject *self, PyObject *args)
return NULL;
Py_RETURN_NONE;
}
+
+/* test Py_AddPendingCalls using threads */
+static int _pending_callback(void *arg)
+{
+ /* we assume the argument is callable object to which we own a reference */
+ PyObject *callable = (PyObject *)arg;
+ PyObject *r = PyObject_CallObject(callable, NULL);
+ Py_DECREF(callable);
+ Py_XDECREF(r);
+ return r != NULL ? 0 : -1;
+}
+
+/* The following requests n callbacks to _pending_callback. It can be
+ * run from any python thread.
+ */
+PyObject *pending_threadfunc(PyObject *self, PyObject *arg)
+{
+ PyObject *callable;
+ int r;
+ if (PyArg_ParseTuple(arg, "O", &callable) == 0)
+ return NULL;
+
+ /* create the reference for the callbackwhile we hold the lock */
+ Py_INCREF(callable);
+
+ Py_BEGIN_ALLOW_THREADS
+ r = Py_AddPendingCall(&_pending_callback, callable);
+ Py_END_ALLOW_THREADS
+
+ if (r<0) {
+ Py_DECREF(callable); /* unsuccessful add, destroy the extra reference */
+ Py_INCREF(Py_False);
+ return Py_False;
+ }
+ Py_INCREF(Py_True);
+ return Py_True;
+}
#endif
/* Some tests of PyString_FromFormat(). This needs more tests. */
@@ -941,6 +978,7 @@ static PyMethodDef TestMethods[] = {
#endif
#ifdef WITH_THREAD
{"_test_thread_state", test_thread_state, METH_VARARGS},
+ {"_pending_threadfunc", pending_threadfunc, METH_VARARGS},
#endif
{"traceback_print", traceback_print, METH_VARARGS},
{NULL, NULL} /* sentinel */