This commit is contained in:
mrkraimer
2018-02-28 09:46:18 -05:00
15 changed files with 72 additions and 66 deletions
+1 -1
View File
@@ -114,7 +114,7 @@ int main(int argc, char *argv[]) {
std::cout<<"Usage: "<<argv[0]<<" [-p <provider>] [-w <timeout>] [-R] <pvname> ...\n";
return 0;
default:
std::cerr<<"Unknown argument: "<<opt<<"\n";
std::cerr<<"Unknown argument: "<<(int)opt<<"\n";
return -1;
}
}
+3 -1
View File
@@ -175,6 +175,8 @@ struct MonTracker : public pvac::ClientChannel::MonitorCallback,
if(n==2) {
// too many updates, re-queue to balance with others
monwork.push(shared_from_this(), evt);
} else if(n==0) {
std::cerr<<"Spurious Data event "<<name<<"\n";
}
}
break;
@@ -212,7 +214,7 @@ int main(int argc, char *argv[]) {
std::cout<<"Usage: "<<argv[0]<<" [-p <provider>] [-w <timeout>] [-r <request>] [-R] <pvname> ...\n";
return 0;
default:
std::cerr<<"Unknown argument: "<<opt<<"\n";
std::cerr<<"Unknown argument: "<<(char)opt<<"\n";
return -1;
}
}
+1
View File
@@ -41,6 +41,7 @@ void alldone(int num)
#endif
pvd::Structure::const_shared_pointer spamtype(pvd::getFieldCreate()->createFieldBuilder()
->setId("epics:nt/NTScalar:1.0")
->add("value", pvd::pvInt)
->createStructure());
+7 -2
View File
@@ -269,6 +269,8 @@ struct Putter : public pvac::ClientChannel::PutCallback
shared_vector<std::string> jarr;
PVStructure::const_shared_pointer current;
virtual void putBuild(const epics::pvData::StructureConstPtr& build, Args& args)
{
if(debug) std::cerr<<"Server defined structure\n"<<build;
@@ -314,13 +316,14 @@ struct Putter : public pvac::ClientChannel::PutCallback
PVStructure* sfld(static_cast<PVStructure*>(fld.get()));
PVScalar* idxfld(sfld->getSubFieldT<PVScalar>("index").get());
PVStringArray::const_svector choices(sfld->getSubFieldT<PVStringArray>("choices")->view());
PVStringArray::const_svector choices(current->getSubFieldT<PVStringArray>("value.choices")->view());
bool found=false;
for(size_t i=0; i<choices.size(); i++) {
if(bare[0]==choices[i]) {
idxfld->putFrom<int64>(i);
found=true;
break;
}
}
@@ -615,9 +618,11 @@ int main (int argc, char *argv[])
pvac::ClientChannel chan(ctxt.connect(pvName));
thework.current = chan.get(timeOut, pvRequest);
if (mode != TerseMode && !quiet) {
std::cout << "Old : ";
printValue(pvName, chan.get(timeOut, pvRequest));
printValue(pvName, thework.current);
}
{
+16 -3
View File
@@ -196,16 +196,29 @@ bool Monitor::poll()
Guard G(impl->mutex);
if(!impl->done && impl->last.next()) {
root = impl->last->pvStructurePtr;
const epics::pvData::PVStructurePtr& ptr = impl->last->pvStructurePtr;
changed = *impl->last->changedBitSet;
overrun = *impl->last->overrunBitSet;
/* copy the exposed PVStructure for two reasons.
* 1. Prevent accidental use of shared container after release()
* 2. Allows caller to cache results of getSubField() until root.get() changes.
*/
if(!root || (void*)root->getField().get()!=(void*)ptr->getField().get()) {
// initial connection, or new type
root = pvd::getPVDataCreate()->createPVStructure(ptr); // also calls copyUnchecked()
} else {
// same type
const_cast<pvd::PVStructure&>(*root).copyUnchecked(*ptr, changed);
}
impl->seenEmpty = false;
} else {
root.reset();
changed.clear();
overrun.clear();
impl->seenEmpty = true;
}
return impl->seenEmpty = !!root;
return !impl->seenEmpty;
}
bool Monitor::complete() const
+19 -1
View File
@@ -104,13 +104,31 @@ struct epicsShareClass Monitor
void cancel();
/** updates root, changed, overrun
*
* @return true if root!=NULL
* @return true if a new update was extracted from the queue.
* @note This method does not block.
* @note MonitorEvent::Data will not be repeated until poll()==false.
* @post root!=NULL (after version 6.0.0)
* @post root!=NULL iff poll()==true (In version 6.0.0)
*/
bool poll();
//! true if all events received.
//! Check after poll()==false
bool complete() const;
/** Monitor update data.
*
* After version 6.0.0
*
* Initially NULL, becomes !NULL the first time poll()==true.
* The PVStructure pointed to be root will presist until
* Monitor reconnect w/ type change. This can be detected
* by comparing `root.get()`. references to root may be cached
* subject to this test.
*
* In version 6.0.0
*
* NULL except after poll()==true. poll()==false sets root=NULL.
* references to root should not be stored between calls to poll().
*/
epics::pvData::PVStructure::const_shared_pointer root;
epics::pvData::BitSet changed,
overrun;
+1 -1
View File
@@ -46,7 +46,7 @@ void startitup() {
the_server = pva::ServerContext::create(pva::ServerContext::Config()
.config(pva::ConfigurationBuilder()
// default to all providers instead of just "local"
.add("EPICS_PVAS_PROVIDER_NAMES", PVACCESS_ALL_PROVIDERS)
.add("EPICS_PVAS_PROVIDER_NAMES", pva::PVACCESS_ALL_PROVIDERS)
.push_map()
// prefer to use EPICS_PVAS_PROVIDER_NAMES
// from environment
+4 -4
View File
@@ -67,19 +67,19 @@ const epics::pvData::int16 PVA_DEFAULT_PRIORITY = 0;
const epics::pvData::uint32 MAX_CHANNEL_NAME_LENGTH = 500;
/** Invalid data type. */
const epics::pvData::int16 INVALID_DATA_TYPE = static_cast<epics::pvData::int16>(0xFFFF);
const epics::pvData::int16 INVALID_DATA_TYPE = 0xFFFF;
/** Invalid IOID. */
const epics::pvData::int32 INVALID_IOID = 0;
/** Default PVA provider name. */
#define PVACCESS_DEFAULT_PROVIDER "local"
const std::string PVACCESS_DEFAULT_PROVIDER;
/** "All-providers registered" PVA provider name. */
#define PVACCESS_ALL_PROVIDERS "<all>"
const std::string PVACCESS_ALL_PROVIDERS;
/** Name of the system env. variable to turn on debugging. */
#define PVACCESS_DEBUG "EPICS_PVA_DEBUG"
const std::string PVACCESS_DEBUG;
}
}
+4
View File
@@ -15,6 +15,10 @@ using std::string;
namespace epics {
namespace pvAccess {
const std::string PVACCESS_DEFAULT_PROVIDER = "local";
const std::string PVACCESS_ALL_PROVIDERS = "<all>";
const std::string PVACCESS_DEBUG = "EPICS_PVA_DEBUG";
Version::Version(std::string const & productName,
std::string const & implementationLangugage,
int majorVersion, int minorVersion,
+5 -5
View File
@@ -337,7 +337,7 @@ void AbstractCodec::processReadSegmented() {
" %s:%d: %s, disconnecting...",
__FILE__, __LINE__, inetAddressToString(*getLastReadBufferSocketAddress()).c_str());
invalidDataStreamHandler();
throw new invalid_data_stream_exception(
throw invalid_data_stream_exception(
"not-a-first segmented message expected");
}
@@ -1586,11 +1586,11 @@ void BlockingServerTCPTransportCodec::destroyAllChannels() {
_socketName.c_str(), _channels.size());
}
std::map<pvAccessID, ServerChannel::shared_pointer>::iterator it = _channels.begin();
for(; it!=_channels.end(); it++)
it->second->destroy();
_channels_t temp;
temp.swap(_channels);
_channels.clear();
for(_channels_t::iterator it(temp.begin()), end(temp.end()); it!=end; ++it)
it->second->destroy();
}
void BlockingServerTCPTransportCodec::internalClose(bool force) {
+5 -32
View File
@@ -74,28 +74,6 @@ TransportRegistry::~TransportRegistry()
if(!transports.empty())
LOG(logLevelWarn, "TransportRegistry destroyed while not empty");
}
/*
void
TransportRegistry::get(const osiSockAddr* address, transportVector_t& output)
{
pvd::Lock guard(_mutex);
transportsMap_t::iterator transportsIter = _transports.find(address);
if(transportsIter != _transports.end())
{
prioritiesMapSharedPtr_t& priorities = transportsIter->second;
size_t i = output.size();
output.resize(output.size() + priorities->size());
for(prioritiesMap_t::iterator prioritiesIter = priorities->begin();
prioritiesIter != priorities->end();
prioritiesIter++, i++)
{
output[i] = prioritiesIter->second;
}
}
}
*/
Transport::shared_pointer TransportRegistry::get(const osiSockAddr& address, epics::pvData::int16 prio)
{
@@ -124,19 +102,14 @@ void TransportRegistry::install(const Transport::shared_pointer& ptr)
Transport::shared_pointer TransportRegistry::remove(Transport::shared_pointer const & transport)
{
assert(!!transport);
const Key key(transport->getRemoteAddress(), transport->getPriority());
Transport::shared_pointer ret;
pvd::Lock guard(_mutex);
for(transports_t::iterator it(transports.begin()), end(transports.end());
it != end; ++it)
{
Transport::shared_pointer& tr = it->second;
if(transport.get() == tr.get()) {
ret.swap(it->second);
transports.erase(it);
break;
}
transports_t::iterator it(transports.find(key));
if(it!=transports.end()) {
ret.swap(it->second);
transports.erase(it);
}
return ret;
}
+3 -1
View File
@@ -3828,7 +3828,9 @@ public:
for(size_t i=0, N=ops.size(); i<N; i++) {
ResponseRequest::shared_pointer R(ops[i].lock());
if(!R) continue;
EXCEPTION_GUARD(R->getRequester()->channelDisconnect(connectionState==Channel::DESTROYED);)
ChannelBaseRequester::shared_pointer req(R->getRequester());
if(!req) continue;
EXCEPTION_GUARD(req->channelDisconnect(connectionState==Channel::DESTROYED);)
}
}
}
+1 -1
View File
@@ -2035,7 +2035,7 @@ void ServerMonitorRequesterImpl::destroy()
// hold a reference to channelMonitor so that _channelMonitor.reset()
// does not call ~Monitor (external code) while we are holding a lock
Monitor::shared_pointer monitor = _channelMonitor;
Monitor::shared_pointer monitor(_channelMonitor);
{
Lock guard(_mutex);
_channel->unregisterRequest(_ioid);
-7
View File
@@ -362,13 +362,6 @@ void ServerContextImpl::shutdown()
void ServerContextImpl::destroyAllTransports()
{
TransportRegistry::transportVector_t transports;
_transportRegistry.toArray(transports);
size_t size = transports.size();
if (size == 0)
return;
// now clear all (release)
_transportRegistry.clear();
}
+2 -7
View File
@@ -72,9 +72,7 @@ public:
} enode;
unsigned Qcnt;
value_type holder;
#ifndef NDEBUG
fair_queue *owner;
#endif
friend class fair_queue;
@@ -82,9 +80,7 @@ public:
entry& operator=(const entry&);
public:
entry() :Qcnt(0), holder()
#ifndef NDEBUG
, owner(NULL)
#endif
{
enode.node.next = enode.node.previous = NULL;
enode.self = this;
@@ -92,9 +88,8 @@ public:
~entry() {
// nodes should be removed from the list before deletion
assert(!enode.node.next && !enode.node.previous);
#ifndef NDEBUG
assert(Qcnt==0 && !holder);
assert(!owner);
#endif
}
};
@@ -144,6 +139,7 @@ public:
bool pop_front_try(value_type& ret)
{
ret.reset();
guard_t G(mutex);
ELLNODE *cur = ellGet(&list); // pop_front
@@ -165,7 +161,6 @@ public:
}
return true;
} else {
ret.reset();
return false;
}
}