From 1ab43405c460cc2dbb038212021493e023191fe7 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Tue, 10 Dec 2013 18:25:46 -0500 Subject: [PATCH] thread safe processing reason Use TLS to ensure that concurrent scanners don't see our reason. --- devsupApp/src/dbdset.c | 35 +++++------------------------------ devsupApp/src/dbrec.c | 8 ++++---- devsupApp/src/pydevsup.h | 4 ++++ devsupApp/src/setup.c | 6 ++++++ 4 files changed, 19 insertions(+), 34 deletions(-) diff --git a/devsupApp/src/dbdset.c b/devsupApp/src/dbdset.c index 37fd667..ea2cd9e 100644 --- a/devsupApp/src/dbdset.c +++ b/devsupApp/src/dbdset.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -35,8 +36,6 @@ typedef struct { int rawsupport; IOSCANPVT scan; - - PyObject *reason; } pyDevice; static long parse_link(dbCommon *prec, const char* src) @@ -131,11 +130,13 @@ static long detach_common(dbCommon *prec) static long process_common(dbCommon *prec) { pyDevice *priv = prec->dpvt; - PyObject *reason = priv->reason; + PyObject *reason = epicsThreadPrivateGet(pyDevReasonID); PyObject *ret; if(!reason) reason = Py_None; + else + epicsThreadPrivateSet(pyDevReasonID, NULL); ret = PyObject_CallMethod(priv->support, "process", "OO", priv->pyrecord, reason); if(!ret) @@ -165,11 +166,6 @@ static long report(int lvl) obj = priv->scanobj ? priv->scanobj : Py_None; printf("IOSCAN: "); PyObject_Print(obj, stdout, 0); - - if(priv->reason) { - printf("Leftover reason!: "); - PyObject_Print(priv->reason, stdout, 0); - } } } PyGILState_Release(pystate); @@ -351,26 +347,6 @@ static long process_record2(dbCommon *prec) return ret; } -int setReasonPyRecord(dbCommon *prec, PyObject *reason) -{ - pyDevice *priv=prec->dpvt; - if(!isPyRecord(prec) || !priv || priv->reason) - return 0; - Py_INCREF(reason); - priv->reason = reason; - return 1; -} - -int clearReasonPyRecord(dbCommon *prec) -{ - pyDevice *priv=prec->dpvt; - if(!isPyRecord(prec) || !priv || !priv->reason) - return 0; - Py_DECREF(priv->reason); - priv->reason = NULL; - return 1; -} - static dsxt pydevsupExt = {&add_record, &del_record}; @@ -438,8 +414,7 @@ void pyDBD_cleanup(void) Py_XDECREF(priv->support); Py_XDECREF(priv->pyrecord); - Py_XDECREF(priv->reason); - priv->support = priv->pyrecord = priv->reason = NULL; + priv->support = priv->pyrecord = NULL; free(priv); } diff --git a/devsupApp/src/dbrec.c b/devsupApp/src/dbrec.c index 3fa3e3e..cdbebf3 100644 --- a/devsupApp/src/dbrec.c +++ b/devsupApp/src/dbrec.c @@ -190,7 +190,7 @@ static PyObject* pyRecord_scan(pyRecord *self, PyObject *args, PyObject *kws) } else { long ret=-1; int ran=0; - setReasonPyRecord(prec, reason); + epicsThreadPrivateSet(pyDevReasonID, reason); Py_BEGIN_ALLOW_THREADS { @@ -206,7 +206,7 @@ static PyObject* pyRecord_scan(pyRecord *self, PyObject *args, PyObject *kws) } Py_END_ALLOW_THREADS - clearReasonPyRecord(prec); + epicsThreadPrivateSet(pyDevReasonID, NULL); if(ran) return PyLong_FromLong(ret); @@ -247,7 +247,7 @@ static PyObject *pyRecord_asyncFinish(pyRecord *self, PyObject *args, PyObject * Py_INCREF(self); /* necessary? */ - setReasonPyRecord(prec, reason); + epicsThreadPrivateSet(pyDevReasonID, reason); Py_BEGIN_ALLOW_THREADS { rset *rsup = prec->rset; @@ -262,7 +262,7 @@ static PyObject *pyRecord_asyncFinish(pyRecord *self, PyObject *args, PyObject * } Py_END_ALLOW_THREADS - clearReasonPyRecord(prec); + epicsThreadPrivateSet(pyDevReasonID, NULL); if(!pact) { PyErr_SetString(PyExc_ValueError, "Python Device record was not active"); diff --git a/devsupApp/src/pydevsup.h b/devsupApp/src/pydevsup.h index 67ad62d..90d2214 100644 --- a/devsupApp/src/pydevsup.h +++ b/devsupApp/src/pydevsup.h @@ -1,6 +1,8 @@ #ifndef PYDEVSUP_H #define PYDEVSUP_H +#include + #if PY_MAJOR_VERSION >= 3 #define PyInt_FromLong PyLong_FromLong #define PyInt_AsLong PyLong_AsLong @@ -23,4 +25,6 @@ int canIOScanRecord(dbCommon *); int setReasonPyRecord(dbCommon *, PyObject *); int clearReasonPyRecord(dbCommon *); +extern epicsThreadPrivateId pyDevReasonID; + #endif // PYDEVSUP_H diff --git a/devsupApp/src/setup.c b/devsupApp/src/setup.c index 75a88b0..c444e73 100644 --- a/devsupApp/src/setup.c +++ b/devsupApp/src/setup.c @@ -29,6 +29,8 @@ typedef struct { const char * const name; } pystate; +epicsThreadPrivateId pyDevReasonID; + #define INITST(hook) {initHook ## hook, #hook } static pystate statenames[] = { INITST(AtIocBuild), @@ -284,6 +286,8 @@ static void cleanupPy(void *junk) pyField_cleanup(); Py_Finalize(); + + epicsThreadPrivateDelete(pyDevReasonID); } /* Initialize the interpreter environment @@ -384,6 +388,8 @@ static void pySetupReg(void) { PyGILState_STATE state; + pyDevReasonID = epicsThreadPrivateCreate(); + setupPyInit(); iocshRegister(&codeDef, &codeRun); iocshRegister(&fileDef, &fileRun);