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