more testing

This commit is contained in:
Michael Davidsaver
2016-01-29 14:04:26 -05:00
parent d54cc78ce8
commit 4f5dd551d9
5 changed files with 226 additions and 56 deletions
+90 -11
View File
@@ -8,12 +8,18 @@ typedef epicsGuardRelease<epicsMutex> UnGuard;
namespace pvd = epics::pvData;
namespace pva = epics::pvAccess;
namespace {
int debugdebug = getenv("TEST_EXTRA_DEBUG")!=NULL;
}
TestChannelRequester::TestChannelRequester()
:laststate(pva::Channel::NEVER_CONNECTED)
{}
void TestChannelRequester::channelCreated(const pvd::Status& status, pva::Channel::shared_pointer const & channel)
{
if(debugdebug)
testDiag("channelCreated %s", channel->getChannelName().c_str());
Guard G(lock);
laststate = pva::Channel::CONNECTED;
this->status = status;
@@ -24,6 +30,8 @@ void TestChannelRequester::channelCreated(const pvd::Status& status, pva::Channe
void TestChannelRequester::channelStateChange(pva::Channel::shared_pointer const & channel,
pva::Channel::ConnectionState connectionState)
{
if(debugdebug)
testDiag("channelStateChange %s %d", channel->getChannelName().c_str(), (int)connectionState);
Guard G(lock);
laststate = connectionState;
wait.trigger();
@@ -60,6 +68,8 @@ void TestChannelMonitorRequester::monitorConnect(pvd::Status const & status,
pvd::MonitorPtr const & monitor,
pvd::StructureConstPtr const & structure)
{
if(debugdebug)
testDiag("monitorConnect %p %d", monitor.get(), (int)status.isSuccess());
Guard G(lock);
connectStatus = status;
dtype = structure;
@@ -69,6 +79,8 @@ void TestChannelMonitorRequester::monitorConnect(pvd::Status const & status,
void TestChannelMonitorRequester::monitorEvent(pvd::MonitorPtr const & monitor)
{
if(debugdebug)
testDiag("monitorEvent %p", monitor.get());
mon = monitor;
eventCnt++;
wait.trigger();
@@ -76,6 +88,8 @@ void TestChannelMonitorRequester::monitorEvent(pvd::MonitorPtr const & monitor)
void TestChannelMonitorRequester::unlisten(pvd::MonitorPtr const & monitor)
{
if(debugdebug)
testDiag("unlisten %p", monitor.get());
Guard G(lock);
unlistend = true;
wait.trigger();
@@ -210,6 +224,8 @@ TestPVChannel::createMonitor(
monitors.insert(ret);
static_cast<TestPVMonitor*>(ret.get())->weakself = ret; // save wrapped weak ref
}
if(debugdebug)
testDiag("TestPVChannel::createMonitor %s %p", pv->name.c_str(), ret.get());
requester->monitorConnect(pvd::Status(), ret, pv->dtype);
return ret;
}
@@ -261,14 +277,21 @@ void TestPVMonitor::destroy()
pvd::Status TestPVMonitor::start()
{
bool wake;
if(debugdebug)
testDiag("TestPVMonitor::start %p", this);
{
Guard G(channel->pv->provider->lock);
if(finalize && buffer.empty())
return pvd::Status();
if(!running) {
wake = running = needWakeup = true;
if(running)
return pvd::Status();
running = true;
if(this->buffer.empty()) {
needWakeup = true;
if(debugdebug)
testDiag(" need wakeup");
}
if(!this->free.empty()) {
@@ -287,14 +310,24 @@ pvd::Status TestPVMonitor::start()
buffer.push_back(monitorElement);
this->free.pop_front();
if(debugdebug)
testDiag(" push current");
} else {
inoverflow = true;
changedMask.clear();
changedMask.set(0);
if(debugdebug)
testDiag(" push overflow");
}
}
(void)wake; // todo notify?
return pvd::Status();
}
pvd::Status TestPVMonitor::stop()
{
if(debugdebug)
testDiag("TestPVMonitor::stop %p", this);
Guard G(channel->pv->provider->lock);
running = false;
return pvd::Status();
@@ -308,14 +341,15 @@ pvd::MonitorElementPtr TestPVMonitor::poll()
ret = buffer.front();
buffer.pop_front();
}
testDiag("pop %p", ret.get());
if(debugdebug)
testDiag("TestPVMonitor::poll %p %p", this, ret.get());
return ret;
}
void TestPVMonitor::release(pvd::MonitorElementPtr const & monitorElement)
{
Guard G(channel->pv->provider->lock);
testDiag("release %p", monitorElement.get());
testDiag("TestPVMonitor::release %p %p", this, monitorElement.get());
if(inoverflow) {
assert(!buffer.empty());
@@ -329,7 +363,7 @@ void TestPVMonitor::release(pvd::MonitorElementPtr const & monitorElement)
overflowMask.clear();
buffer.push_back(monitorElement);
testDiag("overflow resume %p", monitorElement.get());
testDiag("TestPVMonitor::overflow resume %p %p", this, monitorElement.get());
inoverflow = false;
} else {
this->free.push_back(monitorElement);
@@ -348,6 +382,8 @@ TestPV::TestPV(const std::string& name,
void TestPV::post(const pvd::BitSet& changed, bool notify)
{
if(debugdebug)
testDiag("post %s %d", name.c_str(), (int)notify);
Guard G(provider->lock);
channels_t::vector_type toupdate(channels.lock_vector());
@@ -364,12 +400,12 @@ void TestPV::post(const pvd::BitSet& changed, bool notify)
mon->inoverflow = true;
mon->overflowMask.or_and(mon->changedMask, changed); // oflow = prev_changed & new_changed
mon->changedMask |= changed;
testDiag("overflow");
if(debugdebug) testDiag("overflow");
} else {
if(!mon->needWakeup)
mon->needWakeup = mon->buffer.empty();
if(mon->buffer.empty())
mon->needWakeup = true;
AUTO_REF(elem, mon->free.front());
elem->pvStructurePtr->copyUnchecked(*value);
@@ -378,10 +414,12 @@ void TestPV::post(const pvd::BitSet& changed, bool notify)
mon->buffer.push_back(elem);
mon->free.pop_front();
testDiag("push %p", elem.get());
if(debugdebug) testDiag("push %p", elem.get());
}
if(mon->needWakeup && notify) {
if(debugdebug) testDiag(" wakeup");
mon->needWakeup = false;
UnGuard U(G);
mon->requester->monitorEvent(*it2);
}
@@ -466,6 +504,8 @@ TestProvider::createChannel(std::string const & channelName,
} else {
requester->channelCreated(pvd::Status(pvd::Status::STATUSTYPE_ERROR, "PV not found"), ret);
}
if(debugdebug)
testDiag("createChannel %s %p", channelName.c_str(), ret.get());
return ret;
}
@@ -477,3 +517,42 @@ TestProvider::addPV(const std::string& name, const pvd::StructureConstPtr& tdef)
pvs.insert(name, ret);
return ret;
}
void TestProvider::dispatch()
{
Guard G(lock);
if(debugdebug)
testDiag("TestProvider::dispatch");
pvs_t::lock_vector_type allpvs(pvs.lock_vector());
FOREACH(pvit, pvend, allpvs)
{
TestPV *pv = pvit->second.get();
TestPV::channels_t::vector_type channels(pv->channels.lock_vector());
FOREACH(chit, chend, channels)
{
TestPVChannel *chan = chit->get();
TestPVChannel::monitors_t::vector_type monitors(chan->monitors.lock_vector());
if(!chan->isConnected())
continue;
FOREACH(monit, monend, monitors)
{
TestPVMonitor *mon = monit->get();
if(mon->finalize || !mon->running)
continue;
if(mon->needWakeup) {
if(debugdebug)
testDiag(" wakeup monitor %p", mon);
mon->needWakeup = false;
UnGuard U(G);
mon->requester->monitorEvent(*monit);
}
}
}
}
}