Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix enum undef ts bug35 #43

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
120 changes: 79 additions & 41 deletions src/gatePv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,12 @@ extern "C" {
extern void logEventCB(EVENT_ARGS args) { // log event callback
gatePvData::logEventCB(args);
}
extern void propEventCB(EVENT_ARGS args) { // prop event callback
gatePvData::propEventCB(args);
}
extern void propDataCB(EVENT_ARGS args) { // prop data event callback
gatePvData::propDataCB(args);
}
extern void propEventCB(EVENT_ARGS args) { // prop value event callback
gatePvData::propEventCB(args);
}
}

// quick access to global_resources
Expand Down Expand Up @@ -855,17 +858,31 @@ int gatePvData::propMonitor(void)
// gets native element count number of elements:

if(ca_read_access(chID)) {
gateDebug1(5,"gatePvData::propMonitor() type=%ld\n",dataType());
// DBE_PROPERTY data subscription
gateDebug1(5,"gatePvData::propMonitor() dataType=%ld\n",dataType());
rc=ca_create_subscription(dataType(),0,chID,DBE_PROPERTY,
::propEventCB,this,&propID);
::propDataCB,this,&propID);
if(rc != ECA_NORMAL) {
fprintf(stderr,"%s gatePvData::propMonitor: "
"ca_create_subscription failed for %s:\n"
" %s\n",
timeStamp(),name()?name():"Unknown",ca_message(rc));
rc=-1;
} else {
rc=0;
}

// DBE_PROPERTY event subscription
gateDebug1(5,"gatePvData::propMonitor() eventType=%ld\n",eventType());
rc=ca_create_subscription(eventType(),0,chID,DBE_PROPERTY,
::propEventCB,this,&propID);
if(rc != ECA_NORMAL) {
fprintf(stderr,"%s gatePvData::propMonitor: "
"ca_create_subscription event failed for %s:\n"
" %s\n",
timeStamp(),name()?name():"Unknown",ca_message(rc));
rc=-1;
}

if(rc==0) {
markPropMonitored();
#if OMIT_CHECK_EVENT
#else
Expand Down Expand Up @@ -1538,19 +1555,67 @@ void gatePvData::propEventCB(EVENT_ARGS args)
(void *)pv, (void*)pv->vc, (unsigned int)args.type);
gdd* dd;

#ifdef RATE_STATS
++pv->mrg->client_event_count;
#endif

if(args.status==ECA_NORMAL)
{
// only sends event_data and does ADD transactions
if(pv->active())
{
gateDebug2(4,"gatePvData::propEventCB() %s PV %s runEventCB\n",pv->getStateName(),pv->name());
if ((dd = pv->runEventCB(&args))) // Create the value gdd
{
gateDebug2(3,"gatePvData::propEventCB() %s PV %s setEventData\n",pv->getStateName(),pv->name());
#if DEBUG_ENUM
dumpdd(1, "gatePvData::propEventCB setEventData", pv->name(), dd);
#endif
gateDebug2(3,"gatePvData::propEventCB() %s PV %s setEventData\n",pv->getStateName(),pv->name());
#if DEBUG_ENUM
dumpdd(1, "gatePvData::propEventCB setEventData", pv->name(), dd);
#endif
// This dd will have an undefined timeStamp as it comes
// from a dbr_ctrl_* structure
pv->vc->setEventData(dd); // Create new setPropData()???

if (pv->needAddRemove())
{
gateDebug0(5,"gatePvData::propEventCB() need add/remove\n");
pv->markAddRemoveNotNeeded();
pv->vc->vcAdd(ctrlType);
}
else
{
// Post the event
pv->vc->vcPostEvent(pv->mrg->propertyEventMask());
}
}
}
++(pv->event_count);
}
}

void gatePvData::propDataCB(EVENT_ARGS args)
{
gatePvData* pv=(gatePvData*)ca_puser(args.chid);
gateDebug3(5,"gatePvData::propDataCB(gatePvData=%p)(gateVCData=%p) type=%d\n",
(void *)pv, (void*)pv->vc, (unsigned int)args.type);
gdd* dd;

#ifdef RATE_STATS
++pv->mrg->client_event_count;
#endif

#if DEBUG_BEAM
printf("gatePvData::propEventCB(): status=%d %s\n",
printf("gatePvData::propDataCB(): status=%d %s\n",
args.status,
pv->name());
#endif

#if DEBUG_DELAY
if(!strncmp("Xorbit",pv->name(),6)) {
printf("%s gatePvData::propEventCB: %s state=%d\n",timeStamp(),pv->name(),
printf("%s gatePvData::propDataCB: %s state=%d\n",timeStamp(),pv->name(),
pv->getState());
}
#endif
Expand All @@ -1560,53 +1625,26 @@ void gatePvData::propEventCB(EVENT_ARGS args)
// only sends event_data and does ADD transactions
if(pv->active())
{
gateDebug3(5,"gatePvData::propEventCB() %s PV %s propGetPending %d\n",pv->getStateName(),pv->name(),pv->propGetPending());
gateDebug3(5,"gatePvData::propDataCB() %s PV %s propGetPending %d\n",pv->getStateName(),pv->name(),pv->propGetPending());
if(pv->propGetPending()) {
gateDebug1(5,"gatePvData::propEventCB() Ignore first propEvent %s PV\n",pv->getStateName());
gateDebug1(5,"gatePvData::propDataCB() Ignore first propEvent %s PV\n",pv->getStateName());
pv->markPropNoGetPending();
return;
}

gateDebug1(3,"gatePvData::propEventCB() %s PV runDataCB\n",pv->getStateName());
gateDebug1(3,"gatePvData::propDataCB() %s PV runDataCB\n",pv->getStateName());
if ((dd = pv->runDataCB(&args))) // Create the attributes gdd
{
#if DEBUG_BEAM
printf(" dd=%p needAddRemove=%d\n", dd, pv->needAddRemove());
#endif
// Update attribute cache
gateDebug2(3,"gatePvData::propEventCB() %s PV %s setPvData\n",pv->getStateName(),pv->name());
gateDebug2(3,"gatePvData::propDataCB() %s PV %s setPvData\n",pv->getStateName(),pv->name());
#if DEBUG_ENUM
dumpdd(1, "gatePvData::propEventCB setPvData", pv->name(), dd);
dumpdd(1, "gatePvData::propDataCB setPvData", pv->name(), dd);
#endif
pv->vc->setPvData(dd);
}

gateDebug2(4,"gatePvData::propEventCB() %s PV %s runValueDataCB\n",pv->getStateName(),pv->name());
if ((dd = pv->runValueDataCB(&args))) // Create the value gdd
{
#if DEBUG_BEAM
printf(" dd=%p needAddRemove=%d\n", dd, pv->needAddRemove());
#endif
gateDebug2(3,"gatePvData::propEventCB() %s PV %s setEventData\n",pv->getStateName(),pv->name());
#if DEBUG_ENUM
dumpdd(1, "gatePvData::propEventCB setEventData", pv->name(), dd);
#endif
// This dd will have an undefined timeStamp as it comes
// from a dbr_ctrl_* structure
pv->vc->setEventData(dd); // Create new setPropData()???

if (pv->needAddRemove())
{
gateDebug0(5,"gatePvData::propEventCB() need add/remove\n");
pv->markAddRemoveNotNeeded();
pv->vc->vcAdd(ctrlType);
}
else
{
// Post the event
pv->vc->vcPostEvent(pv->mrg->propertyEventMask());
}
}
}
++(pv->event_count);
}
Expand Down
3 changes: 2 additions & 1 deletion src/gatePv.h
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,8 @@ class gatePvData
static void accessCB(ACCESS_ARGS args); // access security callback
static void eventCB(EVENT_ARGS args); // value-changed callback
static void logEventCB(EVENT_ARGS args); // value-changed callback
static void propEventCB(EVENT_ARGS args); // value-changed callback
static void propDataCB(EVENT_ARGS args); // DBE_PROPERTY data-changed callback
static void propEventCB(EVENT_ARGS args); // DBE_PROPERTY value-changed callback
static void alhCB(EVENT_ARGS args); // alh info value-changed callback
static void putCB(EVENT_ARGS args); // put callback
static void getCB(EVENT_ARGS args); // get callback
Expand Down
18 changes: 11 additions & 7 deletions testTop/pyTestsApp/TestCSStudio.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,17 +76,18 @@ def testCSStudio_ValueAndPropMonitor(self):
(ioc_cbref, ioc_uaref, ioc_eventid) = ca.create_subscription(ioc, mask=dbr.DBE_VALUE | dbr.DBE_ALARM, use_time=True, callback=self.onChangeIOC)
(ioc_cbref2, ioc_uaref2, ioc_eventid2) = ca.create_subscription(ioc, mask=dbr.DBE_PROPERTY, use_ctrl=True, callback=self.onChangeIOC)

gwtests.wait_until(lambda: self.eventsReceivedIOC == 2 and self.eventsReceivedGW == 2, 5.0)
gwtests.wait_until(lambda: self.eventsReceivedIOC == 2 and self.eventsReceivedGW == 3, 5.0)

# set value on IOC
ioc_value = ca.create_channel("ioc:gwcachetest")
ca.put(ioc_value, 10.0, wait=True)
if gwtests.verbose:
print("Wrote value 10.0 to ioc:gwcachetest")
sys.stdout.flush()

gwtests.wait_until(lambda: self.eventsReceivedIOC == self.eventsReceivedGW, 5.0)
self.assertTrue(self.eventsReceivedIOC == self.eventsReceivedGW,
"After setting value, no. of received updates differ: GW {0}, IOC {1}"
gwtests.wait_until(lambda: self.eventsReceivedIOC == 3 and self.eventsReceivedGW == 4, 5.0)
self.assertTrue(self.eventsReceivedIOC == 3 and self.eventsReceivedGW == 4,
"After setting value, no. of received updates wrong: GW {0}, IOC {1}"
.format(str(self.eventsReceivedGW), str(self.eventsReceivedIOC)))

(are_diff, diffs) = self.compareStructures()
Expand All @@ -99,13 +100,16 @@ def testCSStudio_ValueAndPropMonitor(self):
ca.put(ioc_hihi, 123.0, wait=True)
if gwtests.verbose:
print("Wrote value 123.0 to ioc:gwcachetest.HIHI")
sys.stdout.flush()

ca.put(ioc_value, 11.0, wait=True)
if gwtests.verbose:
print("Wrote value 11.0 to ioc:gwcachetest")
sys.stdout.flush()

gwtests.wait_until(lambda: self.eventsReceivedIOC == self.eventsReceivedGW, 5.0)
self.assertTrue(self.eventsReceivedIOC == self.eventsReceivedGW,
"After setting property, no. of received updates differ: GW {0}, IOC {1}"
gwtests.wait_until(lambda: self.eventsReceivedIOC == 5 and self.eventsReceivedGW == 6, 5.0)
self.assertTrue(self.eventsReceivedIOC == 5 and self.eventsReceivedGW == 6,
"After setting property, no. of received updates wrong: GW {0}, IOC {1}"
.format(str(self.eventsReceivedGW), str(self.eventsReceivedIOC)))

(are_diff, diffs) = self.compareStructures()
Expand Down
8 changes: 4 additions & 4 deletions testTop/pyTestsApp/TestDBEProp.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ def testPropAlarmLevels(self):

for val in range(10):
ioc.put(val, wait=True)
gwtests.wait_until(lambda: self.eventsReceivedGW == 1 and self.eventsReceivedIOC == 1, 5.0)
gwtests.wait_until(lambda: self.eventsReceivedGW == 2 and self.eventsReceivedIOC == 1, 5.0)
# We get 1 event: at connection
self.assertTrue(self.eventsReceivedGW == 1, 'GW events expected: 1; received: ' + str(self.eventsReceivedGW))
self.assertTrue(self.eventsReceivedGW == 2, 'GW events expected: 2; received: ' + str(self.eventsReceivedGW))
self.assertTrue(self.eventsReceivedIOC == 1, 'IOC events expected: 1; received: ' + str(self.eventsReceivedIOC))

self.eventsReceived = 0
Expand All @@ -69,8 +69,8 @@ def testPropAlarmLevels(self):

# Depending on the IOC (supporting PROPERTY changes on limits or not) we get 0 or 4 events.
# Pass test if updates from IOC act the same as updates from GW
self.assertTrue(self.eventsReceivedGW == self.eventsReceivedIOC,
"Expected equal number of updates; received {0} from GW and {1} from IOC".format(self.eventsReceivedGW, self.eventsReceivedIOC))
self.assertTrue(self.eventsReceivedGW == (self.eventsReceivedIOC + 1),
"Expected GW updates to be one more than IOC; received {0} from GW and {1} from IOC".format(self.eventsReceivedGW, self.eventsReceivedIOC))


if __name__ == '__main__':
Expand Down
2 changes: 1 addition & 1 deletion testTop/pyTestsApp/gwtests.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def setup():
if 'TOP' in os.environ:
gwLocation = os.path.join(os.environ['TOP'], '..')
else:
print("Warning: TOP not set. Using default value of '..'")
print("Warning: TOP not set. Using default value of '../..'")

gwExecutable = os.path.join(gwLocation, 'bin', hostArch, 'gateway')
if not os.path.exists(gwExecutable):
Expand Down