testServer and utils are back alive

This commit is contained in:
Matej Sekoranja
2014-05-22 23:59:35 +02:00
parent cdc03d8e97
commit 82f35f8c38
5 changed files with 307 additions and 246 deletions

View File

@@ -1049,7 +1049,6 @@ private:
String m_channelName;
bool m_printValue;
ChannelGet::shared_pointer m_channelGet;
PVStructure::shared_pointer m_pvStructure;
BitSet::shared_pointer m_bitSet;
Mutex m_pointerMutex;
@@ -1076,9 +1075,9 @@ public:
std::cerr << "[" << getRequesterName() << "] message(" << message << ", " << getMessageTypeName(messageType) << ")" << std::endl;
}
virtual void channelGetConnect(const epics::pvData::Status& status,ChannelGet::shared_pointer const & channelGet,
epics::pvData::PVStructure::shared_pointer const & pvStructure,
epics::pvData::BitSet::shared_pointer const & bitSet)
virtual void channelGetConnect(const epics::pvData::Status& status,
ChannelGet::shared_pointer const & channelGet,
epics::pvData::Structure::const_shared_pointer const & /*structure*/)
{
if (status.isSuccess())
{
@@ -1088,15 +1087,8 @@ public:
std::cerr << "[" << m_channelName << "] channel get create: " << status << std::endl;
}
// assign smart pointers
{
Lock lock(m_pointerMutex);
m_channelGet = channelGet;
m_pvStructure = pvStructure;
m_bitSet = bitSet;
}
channelGet->get(true);
channelGet->lastRequest();
channelGet->get();
}
else
{
@@ -1105,7 +1097,10 @@ public:
}
}
virtual void getDone(const epics::pvData::Status& status)
virtual void getDone(const epics::pvData::Status& status,
ChannelGet::shared_pointer const & /*channelGet*/,
epics::pvData::PVStructure::shared_pointer const & pvStructure,
epics::pvData::BitSet::shared_pointer const & bitSet)
{
if (status.isSuccess())
{
@@ -1118,30 +1113,19 @@ public:
// access smart pointers
{
Lock lock(m_pointerMutex);
m_pvStructure = pvStructure;
m_bitSet = bitSet;
m_done = true;
if (m_printValue)
{
m_done = true;
if (m_printValue)
{
// needed since we access the data
ScopedLock dataLock(m_channelGet);
printValue(m_channelName, m_pvStructure);
}
printValue(m_channelName, m_pvStructure);
}
// this is OK since callee holds also owns it
m_channelGet.reset();
}
}
else
{
std::cerr << "[" << m_channelName << "] failed to get: " << status << std::endl;
{
Lock lock(m_pointerMutex);
// this is OK since caller holds also owns it
m_channelGet.reset();
}
}
m_event.signal();
@@ -1171,10 +1155,10 @@ public:
class ChannelRPCRequesterImpl : public ChannelRPCRequester
{
private:
ChannelRPC::shared_pointer m_channelRPC;
Mutex m_pointerMutex;
Event m_event;
Event m_connectionEvent;
bool m_successfullyConnected;
String m_channelName;
PVStructure::shared_pointer m_lastResponse;
@@ -1182,7 +1166,12 @@ private:
public:
ChannelRPCRequesterImpl(String channelName) : m_channelName(channelName), m_done(false) {}
ChannelRPCRequesterImpl(String channelName) :
m_successfullyConnected(false),
m_channelName(channelName),
m_done(false)
{
}
virtual String getRequesterName()
{
@@ -1194,7 +1183,7 @@ public:
std::cerr << "[" << getRequesterName() << "] message(" << message << ", " << getMessageTypeName(messageType) << ")" << std::endl;
}
virtual void channelRPCConnect(const epics::pvData::Status& status,ChannelRPC::shared_pointer const & channelRPC)
virtual void channelRPCConnect(const epics::pvData::Status& status, ChannelRPC::shared_pointer const & /*channelRPC*/)
{
if (status.isSuccess())
{
@@ -1204,10 +1193,9 @@ public:
std::cerr << "[" << m_channelName << "] channel RPC create: " << status << std::endl;
}
// assign smart pointers
{
{
Lock lock(m_pointerMutex);
m_channelRPC = channelRPC;
m_successfullyConnected = status.isSuccess();
}
m_connectionEvent.signal();
@@ -1219,7 +1207,9 @@ public:
}
}
virtual void requestDone (const epics::pvData::Status &status, epics::pvData::PVStructure::shared_pointer const &pvResponse)
virtual void requestDone (const epics::pvData::Status &status,
ChannelRPC::shared_pointer const & /*channelRPC*/,
epics::pvData::PVStructure::shared_pointer const &pvResponse)
{
if (status.isSuccess())
{
@@ -1240,19 +1230,11 @@ public:
formatNT(std::cout, pvResponse);
std::cout << std::endl;
*/
// this is OK since calle holds also owns it
m_channelRPC.reset();
}
}
else
{
std::cerr << "[" << m_channelName << "] failed to RPC: " << status << std::endl;
{
Lock lock(m_pointerMutex);
// this is OK since caller holds also owns it
m_channelRPC.reset();
}
}
m_event.signal();
@@ -1294,12 +1276,8 @@ public:
return false;
}
bool connected;
{
Lock lock(m_pointerMutex);
connected = (m_channelRPC.get() != 0);
}
return connected ? true : false;
Lock lock(m_pointerMutex);
return m_successfullyConnected;
}
};
@@ -2051,7 +2029,8 @@ int main (int argc, char *argv[])
if (rpcRequesterImpl->waitUntilConnected(timeOut))
{
channelRPC->request(arg, true);
channelRPC->lastRequest();
channelRPC->request(arg);
allOK &= rpcRequesterImpl->waitUntilRPC(timeOut);
if (allOK)
{

View File

@@ -102,7 +102,6 @@ void printValue(String const & channelName, PVStructure::shared_pointer const &
class ChannelGetRequesterImpl : public ChannelGetRequester
{
private:
ChannelGet::shared_pointer m_channelGet;
PVStructure::shared_pointer m_pvStructure;
BitSet::shared_pointer m_bitSet;
Mutex m_pointerMutex;
@@ -125,9 +124,8 @@ class ChannelGetRequesterImpl : public ChannelGetRequester
std::cerr << "[" << getRequesterName() << "] message(" << message << ", " << getMessageTypeName(messageType) << ")" << std::endl;
}
virtual void channelGetConnect(const epics::pvData::Status& status,ChannelGet::shared_pointer const & channelGet,
epics::pvData::PVStructure::shared_pointer const & pvStructure,
epics::pvData::BitSet::shared_pointer const & bitSet)
virtual void channelGetConnect(const epics::pvData::Status& status, ChannelGet::shared_pointer const & channelGet,
epics::pvData::Structure::const_shared_pointer const & /*structure*/)
{
if (status.isSuccess())
{
@@ -137,15 +135,8 @@ class ChannelGetRequesterImpl : public ChannelGetRequester
std::cerr << "[" << m_channelName << "] channel get create: " << status << std::endl;
}
// assign smart pointers
{
Lock lock(m_pointerMutex);
m_channelGet = channelGet;
m_pvStructure = pvStructure;
m_bitSet = bitSet;
}
channelGet->get(true);
channelGet->lastRequest();
channelGet->get();
}
else
{
@@ -154,7 +145,10 @@ class ChannelGetRequesterImpl : public ChannelGetRequester
}
}
virtual void getDone(const epics::pvData::Status& status)
virtual void getDone(const epics::pvData::Status& status,
ChannelGet::shared_pointer const & /*channelGet*/,
epics::pvData::PVStructure::shared_pointer const & pvStructure,
epics::pvData::BitSet::shared_pointer const & bitSet)
{
if (status.isSuccess())
{
@@ -167,30 +161,17 @@ class ChannelGetRequesterImpl : public ChannelGetRequester
// access smart pointers
{
Lock lock(m_pointerMutex);
m_pvStructure = pvStructure;
m_bitSet = bitSet;
m_done = true;
/*
{
// needed since we access the data
ScopedLock dataLock(m_channelGet);
printValue(m_channelName, m_pvStructure);
}
*/
// this is OK since callee holds also owns it
m_channelGet.reset();
}
}
else
{
std::cerr << "[" << m_channelName << "] failed to get: " << status << std::endl;
{
Lock lock(m_pointerMutex);
// this is OK since caller holds also owns it
m_channelGet.reset();
}
}
m_event.signal();

View File

@@ -251,7 +251,6 @@ class AtomicBoolean
class ChannelPutRequesterImpl : public ChannelPutRequester
{
private:
ChannelPut::shared_pointer m_channelPut;
PVStructure::shared_pointer m_pvStructure;
BitSet::shared_pointer m_bitSet;
Mutex m_pointerMutex;
@@ -279,8 +278,7 @@ class ChannelPutRequesterImpl : public ChannelPutRequester
virtual void channelPutConnect(const epics::pvData::Status& status,
ChannelPut::shared_pointer const & channelPut,
epics::pvData::PVStructure::shared_pointer const & pvStructure,
epics::pvData::BitSet::shared_pointer const & bitSet)
epics::pvData::Structure::const_shared_pointer const & /*structure*/)
{
if (status.isSuccess())
{
@@ -290,14 +288,6 @@ class ChannelPutRequesterImpl : public ChannelPutRequester
std::cerr << "[" << m_channelName << "] channel put create: " << status << std::endl;
}
// assign smart pointers
{
Lock lock(m_pointerMutex);
m_channelPut = channelPut;
m_pvStructure = pvStructure;
m_bitSet = bitSet;
}
// we always put all
m_bitSet->set(0);
@@ -311,7 +301,9 @@ class ChannelPutRequesterImpl : public ChannelPutRequester
}
}
virtual void getDone(const epics::pvData::Status& status)
virtual void getDone(const epics::pvData::Status& status, ChannelPut::shared_pointer const & /*channelPut*/,
epics::pvData::PVStructure::shared_pointer const & pvStructure,
epics::pvData::BitSet::shared_pointer const & bitSet)
{
if (status.isSuccess())
{
@@ -323,21 +315,11 @@ class ChannelPutRequesterImpl : public ChannelPutRequester
m_done.set();
/*
// access smart pointers
// do not print old value in terseMode
if (!m_supressGetValue.get())
{
Lock lock(m_pointerMutex);
{
// needed since we access the data
ScopedLock dataLock(m_channelPut);
printValue(m_channelName, m_pvStructure);
}
m_pvStructure = pvStructure;
m_bitSet = bitSet;
}
*/
}
else
@@ -348,7 +330,7 @@ class ChannelPutRequesterImpl : public ChannelPutRequester
m_event->signal();
}
virtual void putDone(const epics::pvData::Status& status)
virtual void putDone(const epics::pvData::Status& status, ChannelPut::shared_pointer const & /*channelPut*/)
{
if (status.isSuccess())
{
@@ -374,6 +356,12 @@ class ChannelPutRequesterImpl : public ChannelPutRequester
return m_pvStructure;
}
BitSet::shared_pointer getBitSet()
{
Lock lock(m_pointerMutex);
return m_bitSet;
}
void resetEvent()
{
Lock lock(m_eventMutex);
@@ -587,7 +575,8 @@ int main (int argc, char *argv[])
// we do a put
putRequesterImpl->resetEvent();
channelPut->put(false);
// note on bitSet: we get all, we set all
channelPut->put(putRequesterImpl->getStructure(), putRequesterImpl->getBitSet());
allOK &= putRequesterImpl->waitUntilDone(timeOut);
if (allOK)

View File

@@ -114,7 +114,7 @@ void get_all()
for (vector<ChannelGet::shared_pointer>::const_iterator i = channelGetList.begin();
i != channelGetList.end();
i++)
(*i)->get(false);
(*i)->get();
// we assume all channels are from the same provider
if (bulkMode) provider->flush();
@@ -125,9 +125,6 @@ void get_all()
class ChannelGetRequesterImpl : public ChannelGetRequester
{
private:
ChannelGet::shared_pointer m_channelGet;
PVStructure::shared_pointer m_pvStructure;
BitSet::shared_pointer m_bitSet;
Event m_event;
Event m_connectionEvent;
String m_channelName;
@@ -153,9 +150,8 @@ public:
}
virtual void channelGetConnect(const epics::pvData::Status& status,
ChannelGet::shared_pointer const & channelGet,
epics::pvData::PVStructure::shared_pointer const & pvStructure,
epics::pvData::BitSet::shared_pointer const & bitSet)
ChannelGet::shared_pointer const & /*channelGet*/,
epics::pvData::Structure::const_shared_pointer const & /*structure*/)
{
if (status.isSuccess())
{
@@ -165,10 +161,6 @@ public:
std::cout << "[" << m_channelName << "] channel get create: " << status.toString() << std::endl;
}
m_channelGet = channelGet;
m_pvStructure = pvStructure;
m_bitSet = bitSet;
m_connectionEvent.signal();
}
else
@@ -177,7 +169,10 @@ public:
}
}
virtual void getDone(const epics::pvData::Status& status)
virtual void getDone(const epics::pvData::Status& status,
ChannelGet::shared_pointer const & /*channelGet*/,
epics::pvData::PVStructure::shared_pointer const & /*pvStructure*/,
epics::pvData::BitSet::shared_pointer const & /*bitSet*/)
{
if (status.isSuccess())
{

View File

@@ -138,7 +138,7 @@ public:
iter++)
{
try {
(*iter)->process(false);
(*iter)->process();
} catch (std::exception &ex) {
std::cerr << "Unhandled exception caught in ProcessAction::run(): " << ex.what() << std::endl;
} catch (...) {
@@ -700,7 +700,8 @@ class ChannelProcessRequesterImpl : public ChannelProcessRequester
//m_channelProcess = channelProcess;
}
virtual void processDone(const epics::pvData::Status& /*status*/)
virtual void processDone(const epics::pvData::Status& /*status*/,
ChannelProcess::shared_pointer const &)
{
//std::cout << "processDone(" << status.toString() << ")" << std::endl;
}
@@ -714,16 +715,17 @@ class MockChannelProcess :
public std::tr1::enable_shared_from_this<MockChannelProcess>
{
private:
String m_channelName;
Channel::shared_pointer m_channel;
ChannelProcessRequester::shared_pointer m_channelProcessRequester;
PVStructure::shared_pointer m_pvStructure;
PVScalarPtr m_valueField;
PVTimeStamp m_timeStamp;
AtomicBoolean m_lastRequest;
protected:
MockChannelProcess(String const & channelName, ChannelProcessRequester::shared_pointer const & channelProcessRequester,
MockChannelProcess(Channel::shared_pointer const & channel, ChannelProcessRequester::shared_pointer const & channelProcessRequester,
PVStructure::shared_pointer const & pvStructure, PVStructure::shared_pointer const & /*pvRequest*/) :
m_channelName(channelName), m_channelProcessRequester(channelProcessRequester), m_pvStructure(pvStructure)
m_channel(channel), m_channelProcessRequester(channelProcessRequester), m_pvStructure(pvStructure)
{
PVACCESS_REFCOUNT_MONITOR_CONSTRUCT(mockChannelProcess);
@@ -755,11 +757,11 @@ protected:
public:
static ChannelProcess::shared_pointer create(
String const & channelName,
Channel::shared_pointer const & channel,
ChannelProcessRequester::shared_pointer const & channelProcessRequester,
PVStructure::shared_pointer const & pvStructure, PVStructure::shared_pointer const & pvRequest)
{
ChannelProcess::shared_pointer thisPtr(new MockChannelProcess(channelName, channelProcessRequester, pvStructure, pvRequest));
ChannelProcess::shared_pointer thisPtr(new MockChannelProcess(channel, channelProcessRequester, pvStructure, pvRequest));
// TODO pvRequest
channelProcessRequester->channelProcessConnect(Status::Ok, thisPtr);
@@ -773,7 +775,7 @@ public:
}
virtual void process(bool lastRequest)
virtual void process()
{
{
ScopedLock lock(shared_from_this());
@@ -877,14 +879,24 @@ public:
m_timeStamp.set(current);
}
m_channelProcessRequester->processDone(Status::Ok);
m_channelProcessRequester->processDone(Status::Ok, shared_from_this());
notifyStructureChanged(m_channelName);
notifyStructureChanged(m_channel->getChannelName());
if (lastRequest)
if (m_lastRequest.get())
destroy();
}
virtual void lastRequest()
{
m_lastRequest.set();
}
virtual Channel::shared_pointer getChannel()
{
return m_channel;
}
virtual void cancel()
{
}
@@ -932,19 +944,20 @@ class MockChannelGet :
public std::tr1::enable_shared_from_this<MockChannelGet>
{
private:
String m_channelName;
Channel::shared_pointer m_channel;
ChannelGetRequester::shared_pointer m_channelGetRequester;
PVStructure::shared_pointer m_pvStructure;
BitSet::shared_pointer m_bitSet;
ChannelProcess::shared_pointer m_channelProcess;
AtomicBoolean m_changed;
AtomicBoolean m_lastRequest;
protected:
MockChannelGet(Channel::shared_pointer const & channel,
ChannelGetRequester::shared_pointer const & channelGetRequester,
PVStructure::shared_pointer const & pvStructure,
PVStructure::shared_pointer const & pvRequest) :
m_channelName(channel->getChannelName()),
m_channel(channel),
m_channelGetRequester(channelGetRequester),
m_pvStructure(getRequestedStructure(pvStructure, pvRequest)),
m_bitSet(new BitSet(m_pvStructure->getNumberFields())),
@@ -967,8 +980,7 @@ public:
structureChangedListeners[channel->getChannelName()].push_back(std::tr1::dynamic_pointer_cast<StructureChangedCallback>(thisPtr));
channelGetRequester->channelGetConnect(Status::Ok, thisPtr,
static_cast<MockChannelGet*>(thisPtr.get())->m_pvStructure,
static_cast<MockChannelGet*>(thisPtr.get())->m_bitSet);
static_cast<MockChannelGet*>(thisPtr.get())->m_pvStructure->getStructure());
return thisPtr;
}
@@ -977,10 +989,10 @@ public:
PVACCESS_REFCOUNT_MONITOR_DESTRUCT(mockChannelGet);
}
virtual void get(bool lastRequest)
virtual void get()
{
if (m_channelProcess)
m_channelProcess->process(false);
m_channelProcess->process();
// TODO far from being thread-safe
if (m_changed.get())
@@ -991,9 +1003,9 @@ public:
else
m_bitSet->clear(0);
m_channelGetRequester->getDone(Status::Ok);
m_channelGetRequester->getDone(Status::Ok, shared_from_this(), m_pvStructure, m_bitSet);
if (lastRequest)
if (m_lastRequest.get())
destroy();
}
@@ -1002,6 +1014,16 @@ public:
m_changed.set();
}
virtual void lastRequest()
{
m_lastRequest.set();
}
virtual Channel::shared_pointer getChannel()
{
return m_channel;
}
virtual void cancel()
{
}
@@ -1012,9 +1034,9 @@ public:
m_channelProcess->destroy();
// remove itself from listeners table
if (structureChangedListeners.count(m_channelName))
if (structureChangedListeners.count(m_channel->getChannelName()))
{
vector<StructureChangedCallback::shared_pointer> &vec = structureChangedListeners[m_channelName];
vector<StructureChangedCallback::shared_pointer> &vec = structureChangedListeners[m_channel->getChannelName()];
for (vector<StructureChangedCallback::shared_pointer>::iterator i = vec.begin();
i != vec.end(); i++)
{
@@ -1043,21 +1065,24 @@ public:
PVACCESS_REFCOUNT_MONITOR_DEFINE(mockChannelPut);
class MockChannelPut : public ChannelPut
class MockChannelPut :
public ChannelPut,
public std::tr1::enable_shared_from_this<MockChannelPut>
{
private:
String m_channelName;
Channel::shared_pointer m_channel;
ChannelPutRequester::shared_pointer m_channelPutRequester;
PVStructure::shared_pointer m_pvStructure;
BitSet::shared_pointer m_bitSet;
ChannelProcess::shared_pointer m_channelProcess;
AtomicBoolean m_lastRequest;
protected:
MockChannelPut(Channel::shared_pointer const & channel,
ChannelPutRequester::shared_pointer const & channelPutRequester,
PVStructure::shared_pointer const & pvStructure,
PVStructure::shared_pointer const & pvRequest) :
m_channelName(channel->getChannelName()),
m_channel(channel),
m_channelPutRequester(channelPutRequester),
m_pvStructure(getRequestedStructure(pvStructure, pvRequest)),
m_bitSet(new BitSet(m_pvStructure->getNumberFields())),
@@ -1075,9 +1100,7 @@ public:
{
ChannelPut::shared_pointer thisPtr(new MockChannelPut(channel, channelPutRequester, pvStructure, pvRequest));
channelPutRequester->channelPutConnect(Status::Ok, thisPtr,
static_cast<MockChannelPut*>(thisPtr.get())->m_pvStructure,
static_cast<MockChannelPut*>(thisPtr.get())->m_bitSet);
static_cast<MockChannelPut*>(thisPtr.get())->m_pvStructure->getStructure());
return thisPtr;
}
@@ -1087,28 +1110,43 @@ public:
}
virtual void put(bool lastRequest)
virtual void put(PVStructure::shared_pointer const & pvPutStructure, BitSet::shared_pointer const & putBitSet)
{
// TODO data - do an actual put !!!
if (m_channelProcess)
m_channelProcess->process(false);
m_channelProcess->process();
m_channelPutRequester->putDone(Status::Ok);
m_channelPutRequester->putDone(Status::Ok, shared_from_this());
notifyStructureChanged(m_channelName);
notifyStructureChanged(m_channel->getChannelName());
if (lastRequest)
if (m_lastRequest.get())
destroy();
}
virtual void get()
{
m_channelPutRequester->getDone(Status::Ok);
m_channelPutRequester->getDone(Status::Ok, shared_from_this(), m_pvStructure, m_bitSet);
if (m_lastRequest.get())
destroy();
}
virtual void cancel()
{
}
virtual void lastRequest()
{
m_lastRequest.set();
}
virtual Channel::shared_pointer getChannel()
{
return m_channel;
}
virtual void destroy()
{
if (m_channelProcess)
@@ -1131,28 +1169,38 @@ public:
PVACCESS_REFCOUNT_MONITOR_DEFINE(mockChannelPutGet);
class MockChannelPutGet : public ChannelPutGet
class MockChannelPutGet :
public ChannelPutGet,
public std::tr1::enable_shared_from_this<ChannelPutGet>
{
private:
String m_channelName;
Channel::shared_pointer m_channel;
ChannelPutGetRequester::shared_pointer m_channelPutGetRequester;
PVStructure::shared_pointer m_getStructure;
BitSet::shared_pointer m_getBitSet;
PVStructure::shared_pointer m_putStructure;
BitSet::shared_pointer m_putBitSet;
ChannelProcess::shared_pointer m_channelProcess;
AtomicBoolean m_lastRequest;
protected:
MockChannelPutGet(Channel::shared_pointer const & channel,
ChannelPutGetRequester::shared_pointer const & channelPutGetRequester,
PVStructure::shared_pointer const & pvStructure,
PVStructure::shared_pointer const & pvRequest) :
m_channelName(channel->getChannelName()),
m_channel(channel),
m_channelPutGetRequester(channelPutGetRequester),
m_getStructure(getRequestedStructure(pvStructure, pvRequest, "getField")),
m_getBitSet(new BitSet(m_getStructure->getNumberFields())),
m_putStructure(getRequestedStructure(pvStructure, pvRequest, "putField")),
m_putBitSet(new BitSet(m_putStructure->getNumberFields())),
m_channelProcess(getChannelProcess(channel, pvRequest))
{
PVACCESS_REFCOUNT_MONITOR_CONSTRUCT(mockChannelPutGet);
// always all
m_getBitSet->set(0);
}
public:
@@ -1165,8 +1213,8 @@ public:
ChannelPutGet::shared_pointer thisPtr(new MockChannelPutGet(channel, channelPutGetRequester, pvStructure, pvRequest));
channelPutGetRequester->channelPutGetConnect(Status::Ok, thisPtr,
static_cast<MockChannelPutGet*>(thisPtr.get())->m_putStructure,
static_cast<MockChannelPutGet*>(thisPtr.get())->m_getStructure);
static_cast<MockChannelPutGet*>(thisPtr.get())->m_putStructure->getStructure(),
static_cast<MockChannelPutGet*>(thisPtr.get())->m_getStructure->getStructure());
return thisPtr;
}
@@ -1176,27 +1224,49 @@ public:
PVACCESS_REFCOUNT_MONITOR_DESTRUCT(mockChannelPutGet);
}
virtual void putGet(bool lastRequest)
virtual void putGet(PVStructure::shared_pointer const & pvPutStructure, BitSet::shared_pointer const & putBitSet)
{
// TODO !!! copy what was put...
if (m_channelProcess)
m_channelProcess->process(false);
m_channelProcess->process();
m_channelPutGetRequester->putGetDone(Status::Ok);
m_channelPutGetRequester->putGetDone(Status::Ok, shared_from_this(), m_getStructure, m_getBitSet);
notifyStructureChanged(m_channelName);
notifyStructureChanged(m_channel->getChannelName());
if (lastRequest)
if (m_lastRequest.get())
destroy();
}
virtual void getGet()
{
m_channelPutGetRequester->getGetDone(Status::Ok);
m_channelPutGetRequester->getGetDone(Status::Ok, shared_from_this(), m_getStructure, m_getBitSet);
if (m_lastRequest.get())
destroy();
}
virtual void getPut()
{
m_channelPutGetRequester->getPutDone(Status::Ok);
// putGet might mess with bitSet
m_putBitSet->clear();
m_putBitSet->set(0);
m_channelPutGetRequester->getPutDone(Status::Ok, shared_from_this(), m_putStructure, m_putBitSet);
if (m_lastRequest.get())
destroy();
}
virtual void lastRequest()
{
m_lastRequest.set();
}
virtual Channel::shared_pointer getChannel()
{
return m_channel;
}
virtual void cancel()
@@ -1224,6 +1294,7 @@ public:
static bool handleHelp(
epics::pvData::PVStructure::shared_pointer const & args,
ChannelRPC::shared_pointer const & channelRPC,
ChannelRPCRequester::shared_pointer const & channelRPCRequester,
String const & helpText
)
@@ -1244,7 +1315,7 @@ static bool handleHelp(
);
static_pointer_cast<PVString>(result->getStringField("value"))->put(helpText);
channelRPCRequester->requestDone(Status::Ok, result);
channelRPCRequester->requestDone(Status::Ok, channelRPC, result);
return true;
}
else
@@ -1256,26 +1327,31 @@ static bool handleHelp(
PVACCESS_REFCOUNT_MONITOR_DEFINE(mockChannelRPC);
class MockChannelRPC : public ChannelRPC
class MockChannelRPC :
public ChannelRPC,
public std::tr1::enable_shared_from_this<ChannelRPC>
{
private:
ChannelRPCRequester::shared_pointer m_channelRPCRequester;
String m_channelName;
Channel::shared_pointer m_channel;
PVStructure::shared_pointer m_pvStructure;
AtomicBoolean m_lastRequest;
protected:
MockChannelRPC(ChannelRPCRequester::shared_pointer const & channelRPCRequester,
String const & channelName, PVStructure::shared_pointer const & pvStructure,
Channel::shared_pointer const & channel, PVStructure::shared_pointer const & pvStructure,
PVStructure::shared_pointer const & /*pvRequest*/) :
m_channelRPCRequester(channelRPCRequester), m_channelName(channelName), m_pvStructure(pvStructure)
m_channelRPCRequester(channelRPCRequester), m_channel(channel), m_pvStructure(pvStructure)
{
PVACCESS_REFCOUNT_MONITOR_CONSTRUCT(mockChannelRPC);
}
public:
static ChannelRPC::shared_pointer create(ChannelRPCRequester::shared_pointer const & channelRPCRequester, String const & channelName, PVStructure::shared_pointer const & pvStructure, PVStructure::shared_pointer const & pvRequest)
static ChannelRPC::shared_pointer create(ChannelRPCRequester::shared_pointer const & channelRPCRequester,
Channel::shared_pointer const & channel,
PVStructure::shared_pointer const & pvStructure, PVStructure::shared_pointer const & pvRequest)
{
ChannelRPC::shared_pointer thisPtr(new MockChannelRPC(channelRPCRequester, channelName, pvStructure, pvRequest));
ChannelRPC::shared_pointer thisPtr(new MockChannelRPC(channelRPCRequester, channel, pvStructure, pvRequest));
// TODO pvRequest
channelRPCRequester->channelRPCConnect(Status::Ok, thisPtr);
return thisPtr;
@@ -1286,9 +1362,10 @@ public:
PVACCESS_REFCOUNT_MONITOR_DESTRUCT(mockChannelRPC);
}
virtual void request(epics::pvData::PVStructure::shared_pointer const & pvArgument, bool lastRequest)
virtual void request(epics::pvData::PVStructure::shared_pointer const & pvArgument)
{
if (m_channelName == "testNTTable")
String channelName = m_channel->getChannelName();
if (channelName == "testNTTable")
{
PVStructure::shared_pointer args(
(pvArgument->getStructure()->getID() == "uri:ev4:nt/2012/pwd:NTURI") ?
@@ -1300,7 +1377,7 @@ public:
"Generates a NTTable structure response with 10 rows and a specified number of columns.\n"
"Columns are labeled 'column<num>' and values are '<num> + random [0..1)'.\n"
"Arguments:\n\tstring columns\tnumber of table columns\n";
if (handleHelp(args, m_channelRPCRequester, helpText))
if (handleHelp(args, shared_from_this(), m_channelRPCRequester, helpText))
return;
PVStringPtr columns = dynamic_pointer_cast<PVString>(args->getSubField("columns"));
@@ -1308,17 +1385,17 @@ public:
{
PVStructure::shared_pointer nullPtr;
Status errorStatus(Status::STATUSTYPE_ERROR, "no string 'columns' argument specified");
m_channelRPCRequester->requestDone(errorStatus, nullPtr);
m_channelRPCRequester->requestDone(errorStatus, shared_from_this(), nullPtr);
}
else
{
int columnsCount = atoi(columns->get().c_str());
PVStructure::shared_pointer result = createNTTable(columnsCount);
generateNTTableDoubleValues(result);
m_channelRPCRequester->requestDone(Status::Ok, result);
m_channelRPCRequester->requestDone(Status::Ok, shared_from_this(), result);
}
}
else if (m_channelName == "testNTNameValue")
else if (channelName == "testNTNameValue")
{
PVStructure::shared_pointer args(
(pvArgument->getStructure()->getID() == "uri:ev4:nt/2012/pwd:NTURI") ?
@@ -1330,7 +1407,7 @@ public:
"Generates a NTNameValue structure response with a specified number of columns.\n"
"Columns are labeled 'name<num>' and values are '<num> + random [0..1)'.\n"
"Arguments:\n\tstring columns\tnumber of columns\n";
if (handleHelp(args, m_channelRPCRequester, helpText))
if (handleHelp(args, shared_from_this(), m_channelRPCRequester, helpText))
return;
PVStringPtr columns = dynamic_pointer_cast<PVString>(args->getSubField("columns"));
@@ -1338,7 +1415,7 @@ public:
{
PVStructure::shared_pointer nullPtr;
Status errorStatus(Status::STATUSTYPE_ERROR, "no string 'columns' argument specified");
m_channelRPCRequester->requestDone(errorStatus, nullPtr);
m_channelRPCRequester->requestDone(errorStatus, shared_from_this(), nullPtr);
}
else
{
@@ -1374,10 +1451,10 @@ public:
mv[r] = rand()/((double)RAND_MAX+1) + (int)(r);
result->getSubField<PVDoubleArray>("value")->replace(freeze(mv));
m_channelRPCRequester->requestDone(Status::Ok, result);
m_channelRPCRequester->requestDone(Status::Ok, shared_from_this(), result);
}
}
else if (m_channelName == "testNTMatrix")
else if (channelName == "testNTMatrix")
{
PVStructure::shared_pointer args(
(pvArgument->getStructure()->getID() == "uri:ev4:nt/2012/pwd:NTURI") ?
@@ -1392,7 +1469,7 @@ public:
"\tstring rows\tnumber of matrix rows\n"
"\tstring columns\tnumber of matrix columns\n"
"\t[string bycolumns\torder matrix values in a column-major order]\n";
if (handleHelp(args, m_channelRPCRequester, helpText))
if (handleHelp(args, shared_from_this(), m_channelRPCRequester, helpText))
return;
PVStringPtr rows = dynamic_pointer_cast<PVString>(args->getSubField("rows"));
@@ -1401,7 +1478,7 @@ public:
{
PVStructure::shared_pointer nullPtr;
Status errorStatus(Status::STATUSTYPE_ERROR, "no string 'rows' and 'columns' arguments specified");
m_channelRPCRequester->requestDone(errorStatus, nullPtr);
m_channelRPCRequester->requestDone(errorStatus, shared_from_this(), nullPtr);
}
else
{
@@ -1439,10 +1516,10 @@ public:
mv[r] = rand()/((double)RAND_MAX+1) + (int)(r/colsVal);
result->getSubField<PVDoubleArray>("value")->replace(freeze(mv));
m_channelRPCRequester->requestDone(Status::Ok, result);
m_channelRPCRequester->requestDone(Status::Ok, shared_from_this(), result);
}
}
else if (m_channelName.find("testImage") == 0)
else if (channelName.find("testImage") == 0)
{
PVStructure::shared_pointer args(
(pvArgument->getStructure()->getID() == "uri:ev4:nt/2012/pwd:NTURI") ?
@@ -1461,7 +1538,7 @@ public:
"\t\t\t\tconvert my_image.png my_image.rgb\n"
"\tstring w\timage width\n"
"\tstring h\timage height\n";
if (handleHelp(args, m_channelRPCRequester, helpText))
if (handleHelp(args, shared_from_this(), m_channelRPCRequester, helpText))
return;
PVStringPtr file = dynamic_pointer_cast<PVString>(args->getSubField("file"));
@@ -1471,7 +1548,7 @@ public:
{
PVStructure::shared_pointer nullPtr;
Status errorStatus(Status::STATUSTYPE_ERROR, "not all 'file', 'w' and 'h' arguments specified");
m_channelRPCRequester->requestDone(errorStatus, nullPtr);
m_channelRPCRequester->requestDone(errorStatus, shared_from_this(), nullPtr);
}
else
{
@@ -1515,47 +1592,47 @@ public:
in.readsome((char*)temp.data(), fileSize);
value->replace(freeze(temp));
m_channelRPCRequester->requestDone(Status::Ok, m_pvStructure);
m_channelRPCRequester->requestDone(Status::Ok, shared_from_this(), m_pvStructure);
// for monitors
notifyStructureChanged(m_channelName);
notifyStructureChanged(channelName);
}
else
{
PVStructure::shared_pointer nullPtr;
Status errorStatus(Status::STATUSTYPE_ERROR, "file size does not match given 'w' and 'h'");
m_channelRPCRequester->requestDone(errorStatus, nullPtr);
m_channelRPCRequester->requestDone(errorStatus, shared_from_this(), nullPtr);
}
}
else
{
PVStructure::shared_pointer nullPtr;
Status errorStatus(Status::STATUSTYPE_ERROR, "failed to open image file specified");
m_channelRPCRequester->requestDone(errorStatus, nullPtr);
m_channelRPCRequester->requestDone(errorStatus, shared_from_this(), nullPtr);
}
}
}
else if (m_channelName == "testNTURI")
else if (channelName == "testNTURI")
{
const String helpText =
"Returns the NTURI structure response identical the NTURI request.\n"
"Arguments: (none)\n";
if (handleHelp(pvArgument, m_channelRPCRequester, helpText))
if (handleHelp(pvArgument, shared_from_this(), m_channelRPCRequester, helpText))
return;
if (pvArgument->getStructure()->getID() != "uri:ev4:nt/2012/pwd:NTURI")
{
PVStructure::shared_pointer nullPtr;
Status errorStatus(Status::STATUSTYPE_ERROR, "argument is not a NTURI structure");
m_channelRPCRequester->requestDone(errorStatus, nullPtr);
m_channelRPCRequester->requestDone(errorStatus, shared_from_this(), nullPtr);
}
else
{
// return argument as result
m_channelRPCRequester->requestDone(Status::Ok, pvArgument);
m_channelRPCRequester->requestDone(Status::Ok, shared_from_this(), pvArgument);
}
}
else if (m_channelName == "testSum") {
else if (channelName == "testSum") {
PVStructure::shared_pointer args(
(pvArgument->getStructure()->getID() == "uri:ev4:nt/2012/pwd:NTURI") ?
@@ -1568,7 +1645,7 @@ public:
"Arguments:\n"
"\tint a\tfirst integer number\n"
"\tint b\tsecond integer number\n";
if (handleHelp(args, m_channelRPCRequester, helpText))
if (handleHelp(args, shared_from_this(), m_channelRPCRequester, helpText))
return;
PVInt::shared_pointer pa = args->getSubField<PVInt>("a");
@@ -1577,7 +1654,7 @@ public:
{
PVStructure::shared_pointer nullPtr;
Status errorStatus(Status::STATUSTYPE_ERROR, "int a and int b arguments are required");
m_channelRPCRequester->requestDone(errorStatus, nullPtr);
m_channelRPCRequester->requestDone(errorStatus, shared_from_this(), nullPtr);
return;
}
@@ -1595,13 +1672,13 @@ public:
PVStructure::shared_pointer result = getPVDataCreate()->createPVStructure(resultStructure);
result->getIntField("c")->put(a+b);
m_channelRPCRequester->requestDone(Status::Ok, result);
m_channelRPCRequester->requestDone(Status::Ok, shared_from_this(), result);
}
else if (m_channelName.find("testServerShutdown") == 0)
else if (channelName.find("testServerShutdown") == 0)
{
PVStructure::shared_pointer nullPtr;
m_channelRPCRequester->requestDone(Status::Ok, nullPtr);
m_channelRPCRequester->requestDone(Status::Ok, shared_from_this(), nullPtr);
testServerShutdown();
}
else
@@ -1611,13 +1688,23 @@ public:
pvArgument->toString(&s);
std::cout << "RPC" << std::endl << s << std::endl;
*/
m_channelRPCRequester->requestDone(Status::Ok, m_pvStructure);
m_channelRPCRequester->requestDone(Status::Ok, shared_from_this(), m_pvStructure);
}
if (lastRequest)
if (m_lastRequest.get())
destroy();
}
virtual void lastRequest()
{
m_lastRequest.set();
}
virtual Channel::shared_pointer getChannel()
{
return m_channel;
}
virtual void cancel()
{
}
@@ -1643,22 +1730,24 @@ public:
PVACCESS_REFCOUNT_MONITOR_DEFINE(mockChannelArray);
class MockChannelArray : public ChannelArray
class MockChannelArray :
public ChannelArray,
public std::tr1::enable_shared_from_this<ChannelArray>
{
private:
Channel::shared_pointer m_channel;
ChannelArrayRequester::shared_pointer m_channelArrayRequester;
PVArray::shared_pointer m_pvArray;
PVArray::shared_pointer m_pvStructureArray;
AtomicBoolean m_lastRequest;
protected:
MockChannelArray(ChannelArrayRequester::shared_pointer const & channelArrayRequester,
MockChannelArray(Channel::shared_pointer const & channel,
ChannelArrayRequester::shared_pointer const & channelArrayRequester,
PVStructure::shared_pointer const & pvStructure, PVStructure::shared_pointer const & /*pvRequest*/) :
m_channelArrayRequester(channelArrayRequester)
m_channel(channel), m_channelArrayRequester(channelArrayRequester)
{
PVACCESS_REFCOUNT_MONITOR_CONSTRUCT(mockChannelArray);
@@ -1669,17 +1758,19 @@ protected:
}
public:
static ChannelArray::shared_pointer create(ChannelArrayRequester::shared_pointer const & channelArrayRequester, PVStructure::shared_pointer const & pvStructure, PVStructure::shared_pointer const & pvRequest)
static ChannelArray::shared_pointer create(Channel::shared_pointer const & channel,
ChannelArrayRequester::shared_pointer const & channelArrayRequester,
PVStructure::shared_pointer const & pvStructure, PVStructure::shared_pointer const & pvRequest)
{
ChannelArray::shared_pointer thisPtr(new MockChannelArray(channelArrayRequester, pvStructure, pvRequest));
ChannelArray::shared_pointer thisPtr(new MockChannelArray(channel, channelArrayRequester, pvStructure, pvRequest));
PVArray::shared_pointer array(static_cast<MockChannelArray*>(thisPtr.get())->m_pvArray);
if (array.get())
channelArrayRequester->channelArrayConnect(Status::Ok, thisPtr, array);
channelArrayRequester->channelArrayConnect(Status::Ok, thisPtr, array->getArray());
else
{
Status errorStatus(Status::STATUSTYPE_ERROR, "no 'value' subfield of array type");
channelArrayRequester->channelArrayConnect(errorStatus, thisPtr, array);
channelArrayRequester->channelArrayConnect(errorStatus, thisPtr, Array::const_shared_pointer());
}
return thisPtr;
@@ -1713,39 +1804,42 @@ public:
to->replace(freeze(temp));
}
virtual void putArray(bool lastRequest, size_t offset, size_t count)
virtual void putArray(PVArray::shared_pointer const & pvArray, size_t offset, size_t count, size_t stride)
{
// TODO stride support !!!
size_t o = offset;
if (count == 0) count = m_pvArray->getLength();
if (count == 0) count = pvArray->getLength();
size_t c = count;
Field::const_shared_pointer field = m_pvArray->getField();
Field::const_shared_pointer field = pvArray->getField();
Type type = field->getType();
if (type == scalarArray)
{
switch (std::tr1::static_pointer_cast<const ScalarArray>(field)->getElementType())
{
case pvBoolean: put<PVBooleanArray>(m_pvArray, m_pvStructureArray, o, c); break;
case pvByte: put<PVByteArray>(m_pvArray, m_pvStructureArray, o, c); break;
case pvShort: put<PVShortArray>(m_pvArray, m_pvStructureArray, o, c); break;
case pvInt: put<PVIntArray>(m_pvArray, m_pvStructureArray, o, c); break;
case pvLong: put<PVLongArray>(m_pvArray, m_pvStructureArray, o, c); break;
case pvUByte: put<PVUByteArray>(m_pvArray, m_pvStructureArray, o, c); break;
case pvUShort: put<PVUShortArray>(m_pvArray, m_pvStructureArray, o, c); break;
case pvUInt: put<PVUIntArray>(m_pvArray, m_pvStructureArray, o, c); break;
case pvULong: put<PVULongArray>(m_pvArray, m_pvStructureArray, o, c); break;
case pvFloat: put<PVFloatArray>(m_pvArray, m_pvStructureArray, o, c); break;
case pvDouble: put<PVDoubleArray>(m_pvArray, m_pvStructureArray, o, c); break;
case pvString: put<PVStringArray>(m_pvArray, m_pvStructureArray, o, c); break;
case pvBoolean: put<PVBooleanArray>(pvArray, m_pvStructureArray, o, c); break;
case pvByte: put<PVByteArray>(pvArray, m_pvStructureArray, o, c); break;
case pvShort: put<PVShortArray>(pvArray, m_pvStructureArray, o, c); break;
case pvInt: put<PVIntArray>(pvArray, m_pvStructureArray, o, c); break;
case pvLong: put<PVLongArray>(pvArray, m_pvStructureArray, o, c); break;
case pvUByte: put<PVUByteArray>(pvArray, m_pvStructureArray, o, c); break;
case pvUShort: put<PVUShortArray>(pvArray, m_pvStructureArray, o, c); break;
case pvUInt: put<PVUIntArray>(pvArray, m_pvStructureArray, o, c); break;
case pvULong: put<PVULongArray>(pvArray, m_pvStructureArray, o, c); break;
case pvFloat: put<PVFloatArray>(pvArray, m_pvStructureArray, o, c); break;
case pvDouble: put<PVDoubleArray>(pvArray, m_pvStructureArray, o, c); break;
case pvString: put<PVStringArray>(pvArray, m_pvStructureArray, o, c); break;
}
}
else if (type == structureArray)
put<PVStructureArray>(m_pvArray, m_pvStructureArray, o, c);
put<PVStructureArray>(pvArray, m_pvStructureArray, o, c);
else if (type == unionArray)
put<PVUnionArray>(m_pvArray, m_pvStructureArray, o, c);
put<PVUnionArray>(pvArray, m_pvStructureArray, o, c);
m_channelArrayRequester->putArrayDone(Status::Ok);
if (lastRequest)
m_channelArrayRequester->putArrayDone(Status::Ok, shared_from_this());
if (m_lastRequest.get())
destroy();
}
@@ -1765,8 +1859,10 @@ public:
}
virtual void getArray(bool lastRequest, size_t offset, size_t count)
virtual void getArray(size_t offset, size_t count, size_t stride)
{
// TODO stride support !!!
size_t o = offset;
if (count == 0) count = m_pvStructureArray->getLength();
size_t c = count;
@@ -1796,12 +1892,13 @@ public:
else if (type == unionArray)
get<PVUnionArray>(m_pvStructureArray, m_pvArray, o, c);
m_channelArrayRequester->getArrayDone(Status::Ok);
if (lastRequest)
m_channelArrayRequester->getArrayDone(Status::Ok, shared_from_this(), m_pvArray);
if (m_lastRequest.get())
destroy();
}
virtual void setLength(bool lastRequest, size_t length, size_t capacity)
virtual void setLength(size_t length, size_t capacity)
{
if (capacity > 0) {
m_pvStructureArray->setCapacity(capacity);
@@ -1809,11 +1906,32 @@ public:
m_pvStructureArray->setLength(length);
m_channelArrayRequester->setLengthDone(Status::Ok);
if (lastRequest)
m_channelArrayRequester->setLengthDone(Status::Ok, shared_from_this());
if (m_lastRequest.get())
destroy();
}
virtual void getLength()
{
m_channelArrayRequester->getLengthDone(Status::Ok, shared_from_this(),
m_pvStructureArray->getLength(), m_pvStructureArray->getCapacity());
if (m_lastRequest.get())
destroy();
}
virtual void lastRequest()
{
m_lastRequest.set();
}
virtual Channel::shared_pointer getChannel()
{
return m_channel;
}
virtual void cancel()
{
}
@@ -2274,7 +2392,7 @@ public:
ChannelProcessRequester::shared_pointer const & channelProcessRequester,
epics::pvData::PVStructure::shared_pointer const & pvRequest)
{
return MockChannelProcess::create(m_name, channelProcessRequester, m_pvStructure, pvRequest);
return MockChannelProcess::create(shared_from_this(), channelProcessRequester, m_pvStructure, pvRequest);
}
virtual ChannelGet::shared_pointer createChannelGet(
@@ -2301,7 +2419,7 @@ public:
virtual ChannelRPC::shared_pointer createChannelRPC(ChannelRPCRequester::shared_pointer const & channelRPCRequester,
epics::pvData::PVStructure::shared_pointer const & pvRequest)
{
return MockChannelRPC::create(channelRPCRequester, m_name, m_pvStructure, pvRequest);
return MockChannelRPC::create(channelRPCRequester, shared_from_this(), m_pvStructure, pvRequest);
}
virtual epics::pvData::Monitor::shared_pointer createMonitor(
@@ -2315,7 +2433,7 @@ public:
ChannelArrayRequester::shared_pointer const & channelArrayRequester,
epics::pvData::PVStructure::shared_pointer const & pvRequest)
{
return MockChannelArray::create(channelArrayRequester, m_pvStructure, pvRequest);
return MockChannelArray::create(shared_from_this(), channelArrayRequester, m_pvStructure, pvRequest);
}
virtual void printInfo() {
@@ -2578,8 +2696,7 @@ void testServer(int timeToRun)
//ServerContextImpl::shared_pointer ctx = ServerContextImpl::create();
ctx = ServerContextImpl::create();
ChannelAccess::shared_pointer channelAccess = getChannelProviderRegistry();
ctx->initialize(channelAccess);
ctx->initialize(getChannelProviderRegistry());
ctx->printInfo();