Mercurial > pymonkey
changeset 87:345d4c0e3dd3
Thread safety exceptions are now properly raised by all relevant pymonkey functions.
author | Atul Varma <varmaa@toolness.com> |
---|---|
date | Sun, 09 Aug 2009 16:17:25 -0700 |
parents | 16a3e99e9b77 |
children | 0b2970e8cd67 |
files | context.c runtime.c runtime.h test_pymonkey.py |
diffstat | 4 files changed, 33 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/context.c Sun Aug 09 15:46:40 2009 -0700 +++ b/context.c Sun Aug 09 16:17:25 2009 -0700 @@ -113,6 +113,7 @@ static PyObject * PYM_getObjectPrivate(PYM_JSContextObject *self, PyObject *args) { + PYM_SANITY_CHECK(self->runtime); PYM_JSObject *object; if (!PyArg_ParseTuple(args, "O!", &PYM_JSObjectType, &object)) @@ -152,6 +153,7 @@ static PyObject * PYM_clearObjectPrivate(PYM_JSContextObject *self, PyObject *args) { + PYM_SANITY_CHECK(self->runtime); PYM_JSObject *object; if (!PyArg_ParseTuple(args, "O!", &PYM_JSObjectType, &object)) @@ -185,6 +187,7 @@ static PyObject * PYM_newObject(PYM_JSContextObject *self, PyObject *args) { + PYM_SANITY_CHECK(self->runtime); PyObject *privateObj = NULL; if (!PyArg_ParseTuple(args, "|O", &privateObj)) @@ -204,6 +207,7 @@ static PyObject * PYM_getProperty(PYM_JSContextObject *self, PyObject *args) { + PYM_SANITY_CHECK(self->runtime); #ifndef Py_UNICODE_WIDE PYM_JSObject *object; Py_UNICODE *string; @@ -244,6 +248,7 @@ static PyObject * PYM_gc(PYM_JSContextObject *self, PyObject *args) { + PYM_SANITY_CHECK(self->runtime); JS_GC(self->cx); Py_RETURN_NONE; } @@ -251,6 +256,7 @@ static PyObject * PYM_initStandardClasses(PYM_JSContextObject *self, PyObject *args) { + PYM_SANITY_CHECK(self->runtime); PYM_JSObject *object; if (!PyArg_ParseTuple(args, "O!", &PYM_JSObjectType, &object)) @@ -267,6 +273,7 @@ static PyObject * PYM_evaluateScript(PYM_JSContextObject *self, PyObject *args) { + PYM_SANITY_CHECK(self->runtime); PYM_JSObject *object; const char *source; int sourceLen; @@ -296,6 +303,7 @@ static PyObject * PYM_defineProperty(PYM_JSContextObject *self, PyObject *args) { + PYM_SANITY_CHECK(self->runtime); PYM_JSObject *object; PyObject *value; const char *name; @@ -324,6 +332,7 @@ static PyObject * PYM_callFunction(PYM_JSContextObject *self, PyObject *args) { + PYM_SANITY_CHECK(self->runtime); PYM_JSObject *obj; PYM_JSFunction *fun; PyObject *funcArgs; @@ -368,6 +377,7 @@ static PyObject * PYM_newFunction(PYM_JSContextObject *self, PyObject *args) { + PYM_SANITY_CHECK(self->runtime); PyObject *callable; const char *name; @@ -380,6 +390,7 @@ static PyObject * PYM_setOperationCallback(PYM_JSContextObject *self, PyObject *args) { + PYM_SANITY_CHECK(self->runtime); PyObject *callable; if (!PyArg_ParseTuple(args, "O", &callable))
--- a/runtime.c Sun Aug 09 15:46:40 2009 -0700 +++ b/runtime.c Sun Aug 09 16:17:25 2009 -0700 @@ -46,6 +46,7 @@ self = (PYM_JSRuntimeObject *) type->tp_alloc(type, 0); if (self != NULL) { + self->thread = PyThread_get_thread_ident(); self->rt = NULL; self->cx = NULL; self->objects.ops = NULL; @@ -106,6 +107,7 @@ static PyObject * PYM_newContext(PYM_JSRuntimeObject *self, PyObject *args) { + PYM_SANITY_CHECK(self); JSContext *cx = JS_NewContext(self->rt, 8192); if (cx == NULL) { PyErr_SetString(PYM_error, "JS_NewContext() failed");
--- a/runtime.h Sun Aug 09 15:46:40 2009 -0700 +++ b/runtime.h Sun Aug 09 16:17:25 2009 -0700 @@ -40,12 +40,20 @@ #include <jsapi.h> #include <jsdhash.h> #include <Python/Python.h> +#include <Python/pythread.h> + +#define PYM_SANITY_CHECK(runtime) \ + if (PyThread_get_thread_ident() != runtime->thread) { \ + PyErr_SetString(PYM_error, "Function called from wrong thread"); \ + return NULL; \ + } typedef struct { PyObject_HEAD JSRuntime *rt; JSContext *cx; JSDHashTable objects; + long thread; } PYM_JSRuntimeObject; extern PyTypeObject PYM_JSRuntimeType;
--- a/test_pymonkey.py Sun Aug 09 15:46:40 2009 -0700 +++ b/test_pymonkey.py Sun Aug 09 16:17:25 2009 -0700 @@ -31,6 +31,18 @@ was_raised = True self.assertTrue(was_raised) + def testThreadSafetyExceptionIsRaised(self): + stuff = {} + def make_runtime(): + stuff['rt'] = pymonkey.Runtime() + thread = threading.Thread(target = make_runtime) + thread.start() + thread.join() + self.assertRaises(pymonkey.error, + stuff['rt'].new_context) + self.assertEqual(self.last_exception.message, + 'Function called from wrong thread') + def testClearObjectPrivateWorks(self): class Foo(object): pass