enable I/O Intr
This commit is contained in:
@ -15,6 +15,7 @@
|
||||
#include <recGbl.h>
|
||||
#include <alarm.h>
|
||||
#include <ellLib.h>
|
||||
#include <dbScan.h>
|
||||
#include <cantProceed.h>
|
||||
|
||||
#include "pydevsup.h"
|
||||
@ -31,6 +32,9 @@ typedef struct {
|
||||
PyObject *pyrecord;
|
||||
PyObject *support;
|
||||
|
||||
int allowscan;
|
||||
IOSCANPVT scan;
|
||||
|
||||
PyObject *reason;
|
||||
} pyDevice;
|
||||
|
||||
@ -49,6 +53,7 @@ static long parse_link(dbCommon *prec, const char* src)
|
||||
return -1;
|
||||
|
||||
if(!PyArg_ParseTuple(ret, "OO", &priv->pyrecord, &priv->support)) {
|
||||
priv->pyrecord = priv->support = NULL; /* paranoia */
|
||||
Py_DECREF(ret);
|
||||
return -1;
|
||||
}
|
||||
@ -98,6 +103,20 @@ static long process_common(dbCommon *prec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int allow_ioscan(pyDevice *priv)
|
||||
{
|
||||
PyObject *ret = PyObject_CallMethod(priv->support, "allowScan", "O", priv->pyrecord);
|
||||
if(!ret || !PyObject_IsTrue(ret)) {
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
Py_XDECREF(ret);
|
||||
return 0;
|
||||
} else {
|
||||
Py_DECREF(ret);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static long init_record(dbCommon *prec)
|
||||
{
|
||||
return 0;
|
||||
@ -146,6 +165,7 @@ static long add_record(dbCommon *prec)
|
||||
priv = callocMustSucceed(1, sizeof(*priv), "init_record");
|
||||
priv->precord = prec;
|
||||
priv->plink = ent.pfield;
|
||||
scanIoInit(&priv->scan);
|
||||
|
||||
if(priv->plink->type != INST_IO) {
|
||||
fprintf(stderr, "%s: Has invalid link type %d\n", prec->name, priv->plink->type);
|
||||
@ -194,7 +214,7 @@ static long del_record(dbCommon *prec)
|
||||
pyDevice *priv=prec->dpvt;
|
||||
PyGILState_STATE pystate;
|
||||
|
||||
if(!priv)
|
||||
if(!priv || !priv->support)
|
||||
return 0;
|
||||
|
||||
pystate = PyGILState_Ensure();
|
||||
@ -212,6 +232,22 @@ static long del_record(dbCommon *prec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long get_iointr_info(int dir, dbCommon *prec, IOSCANPVT *scan)
|
||||
{
|
||||
pyDevice *priv=prec->dpvt;
|
||||
if(!priv || !priv->support)
|
||||
return 0;
|
||||
|
||||
if(dir==0) {
|
||||
if(!allow_ioscan(priv))
|
||||
return S_db_Blocked;
|
||||
priv->allowscan = 1;
|
||||
} else
|
||||
priv->allowscan = 0;
|
||||
*scan = priv->scan;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long process_record(dbCommon *prec)
|
||||
{
|
||||
pyDevice *priv = prec->dpvt;
|
||||
@ -273,14 +309,28 @@ typedef struct {
|
||||
DEVSUPFUN proc;
|
||||
} dset5;
|
||||
|
||||
static dset5 pydevsupCom = {{5, NULL, (DEVSUPFUN)&init, (DEVSUPFUN)&init_record, NULL}, (DEVSUPFUN)&process_record};
|
||||
static dset5 pydevsupCom2 = {{5, NULL, (DEVSUPFUN)&init, (DEVSUPFUN)&init_record2, NULL}, (DEVSUPFUN)&process_record};
|
||||
static dset5 pydevsupCom = {{5, NULL, (DEVSUPFUN)&init,
|
||||
(DEVSUPFUN)&init_record,
|
||||
(DEVSUPFUN)&get_iointr_info},
|
||||
(DEVSUPFUN)&process_record};
|
||||
static dset5 pydevsupCom2 = {{5, NULL, (DEVSUPFUN)&init,
|
||||
(DEVSUPFUN)&init_record2,
|
||||
(DEVSUPFUN)&get_iointr_info},
|
||||
(DEVSUPFUN)&process_record};
|
||||
|
||||
int isPyRecord(dbCommon *prec)
|
||||
{
|
||||
return prec->dset==(dset*)&pydevsupCom || prec->dset==(dset*)&pydevsupCom2;
|
||||
}
|
||||
|
||||
int canIOScanRecord(dbCommon *prec)
|
||||
{
|
||||
pyDevice *priv=prec->dpvt;
|
||||
if(isPyRecord(prec))
|
||||
return 0;
|
||||
return priv->allowscan;
|
||||
}
|
||||
|
||||
/* Called with GIL locked */
|
||||
void pyDBD_cleanup(void)
|
||||
{
|
||||
@ -300,12 +350,9 @@ void pyDBD_cleanup(void)
|
||||
|
||||
/* cleanup and dealloc */
|
||||
|
||||
if(priv->support)
|
||||
Py_DECREF(priv->support);
|
||||
if(priv->pyrecord)
|
||||
Py_DECREF(priv->pyrecord);
|
||||
if(priv->reason)
|
||||
Py_DECREF(priv->reason);
|
||||
Py_XDECREF(priv->support);
|
||||
Py_XDECREF(priv->pyrecord);
|
||||
Py_XDECREF(priv->reason);
|
||||
priv->support = priv->pyrecord = priv->reason = NULL;
|
||||
|
||||
free(priv);
|
||||
|
@ -18,6 +18,7 @@ typedef struct {
|
||||
PyObject_HEAD
|
||||
|
||||
DBENTRY entry;
|
||||
int ispyrec;
|
||||
} pyRecord;
|
||||
|
||||
static void pyRecord_dealloc(pyRecord *self)
|
||||
@ -33,6 +34,7 @@ static PyObject* pyRecord_new(PyTypeObject *type, PyObject *args, PyObject *kws)
|
||||
self = (pyRecord*)type->tp_alloc(type, 0);
|
||||
if(self) {
|
||||
dbInitEntry(pdbbase, &self->entry);
|
||||
self->ispyrec = isPyRecord(self->entry.precnode->precord);
|
||||
}
|
||||
return (PyObject*)self;
|
||||
}
|
||||
@ -50,6 +52,11 @@ static int pyRecord_Init(pyRecord *self, PyObject *args, PyObject *kws)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject* pyRecord_ispyrec(pyRecord *self)
|
||||
{
|
||||
return PyBool_FromLong(self->ispyrec);
|
||||
}
|
||||
|
||||
static int pyRecord_compare(pyRecord *A, pyRecord *B)
|
||||
{
|
||||
dbCommon *a=A->entry.precnode->precord,
|
||||
@ -124,11 +131,12 @@ static PyObject* pyRecord_scan(pyRecord *self, PyObject *args, PyObject *kws)
|
||||
{
|
||||
dbCommon *prec = self->entry.precnode->precord;
|
||||
|
||||
static char* names[] = {"sync", "reason", NULL};
|
||||
static char* names[] = {"sync", "reason", "force", NULL};
|
||||
unsigned int force = 0;
|
||||
PyObject *reason = Py_None;
|
||||
PyObject *sync = Py_False;
|
||||
|
||||
if(!PyArg_ParseTupleAndKeywords(args, kws, "|OO", names, &sync, &reason))
|
||||
if(!PyArg_ParseTupleAndKeywords(args, kws, "|OOI", names, &sync, &reason, &force))
|
||||
return NULL;
|
||||
|
||||
if(!PyObject_IsTrue(sync)) {
|
||||
@ -136,20 +144,32 @@ static PyObject* pyRecord_scan(pyRecord *self, PyObject *args, PyObject *kws)
|
||||
Py_RETURN_NONE;
|
||||
|
||||
} else {
|
||||
long ret;
|
||||
long ret=-1;
|
||||
int ran=1;
|
||||
setReasonPyRecord(prec, reason);
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS {
|
||||
|
||||
dbScanLock(prec);
|
||||
ret = dbProcess(prec);
|
||||
if(force==1
|
||||
|| (force==0 && prec->scan==menuScanPassive)
|
||||
|| (force==2 && prec->scan==menuScanI_O_Intr && canIOScanRecord(prec)))
|
||||
{
|
||||
ran = 1;
|
||||
ret = dbProcess(prec);
|
||||
}
|
||||
dbScanUnlock(prec);
|
||||
|
||||
} Py_END_ALLOW_THREADS
|
||||
|
||||
clearReasonPyRecord(prec);
|
||||
|
||||
return PyLong_FromLong(ret);
|
||||
if(ran)
|
||||
return PyLong_FromLong(ret);
|
||||
else {
|
||||
PyErr_SetNone(PyExc_RuntimeError);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -181,7 +201,7 @@ static PyObject *pyRecord_asyncFinish(pyRecord *self, PyObject *args, PyObject *
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_INCREF(self);
|
||||
Py_INCREF(self); /* necessary? */
|
||||
|
||||
setReasonPyRecord(prec, reason);
|
||||
|
||||
@ -213,6 +233,8 @@ static PyObject *pyRecord_asyncFinish(pyRecord *self, PyObject *args, PyObject *
|
||||
static PyMethodDef pyRecord_methods[] = {
|
||||
{"name", (PyCFunction)pyRecord_name, METH_NOARGS,
|
||||
"Return record name string"},
|
||||
{"isPyRecord", (PyCFunction)pyRecord_ispyrec, METH_NOARGS,
|
||||
"Is this record using Python Device."},
|
||||
{"info", (PyCFunction)pyRecord_info, METH_VARARGS,
|
||||
"Lookup info name\ninfo(name, def=None)"},
|
||||
{"infos", (PyCFunction)pyRecord_infos, METH_NOARGS,
|
||||
|
@ -11,6 +11,7 @@ int pyRecord_prepare(void);
|
||||
void pyRecord_setup(PyObject *module);
|
||||
|
||||
int isPyRecord(dbCommon *);
|
||||
int canIOScanRecord(dbCommon *);
|
||||
int setReasonPyRecord(dbCommon *, PyObject *);
|
||||
int clearReasonPyRecord(dbCommon *);
|
||||
|
||||
|
Reference in New Issue
Block a user