This commit is contained in:
+1
-1
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user