caProvider: Convert caChannelList into a tsDLList
This should provide a significant performance boost when creating many thousands of CA channels. The only time it is necessary to traverse the list is in the CAChannelProvider's destructor; when individual channels are added or destroyed they can insert or remove themselves from the list without having to do a search.
This commit is contained in:
@ -132,7 +132,7 @@ void CAChannel::activate(short priority)
|
||||
channelCreated = true;
|
||||
CAChannelProviderPtr provider(channelProvider.lock());
|
||||
if (provider)
|
||||
provider->addChannel(shared_from_this());
|
||||
provider->addChannel(*this);
|
||||
EXCEPTION_GUARD(req->channelCreated(Status::Ok, shared_from_this()));
|
||||
}
|
||||
else {
|
||||
@ -167,10 +167,14 @@ void CAChannel::disconnectChannel()
|
||||
/* Clear CA Channel */
|
||||
Attach to(ca_context);
|
||||
int result = ca_clear_channel(channelID);
|
||||
if (result == ECA_NORMAL) return;
|
||||
string mess("CAChannel::disconnectChannel() ");
|
||||
mess += ca_message(result);
|
||||
cerr << mess << endl;
|
||||
if (result != ECA_NORMAL) {
|
||||
string mess("CAChannel::disconnectChannel() ");
|
||||
mess += ca_message(result);
|
||||
cerr << mess << endl;
|
||||
}
|
||||
CAChannelProviderPtr provider(channelProvider.lock());
|
||||
if (provider)
|
||||
provider->delChannel(*this);
|
||||
}
|
||||
|
||||
chid CAChannel::getChannelID()
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <epicsMutex.h>
|
||||
#include <epicsEvent.h>
|
||||
#include <cadef.h>
|
||||
#include <tsDLList.h>
|
||||
|
||||
#include <pv/pvAccess.h>
|
||||
|
||||
@ -66,6 +67,7 @@ private:
|
||||
|
||||
class CAChannel :
|
||||
public Channel,
|
||||
public tsDLNode<CAChannel>,
|
||||
public NotifierClient,
|
||||
public std::tr1::enable_shared_from_this<CAChannel>
|
||||
{
|
||||
|
@ -31,22 +31,9 @@ CAChannelProvider::CAChannelProvider(const std::tr1::shared_ptr<Configuration> &
|
||||
|
||||
CAChannelProvider::~CAChannelProvider()
|
||||
{
|
||||
std::queue<CAChannelPtr> channelQ;
|
||||
{
|
||||
std::vector<CAChannelWPtr>::iterator it;
|
||||
epicsGuard<epicsMutex> G(channelListMutex);
|
||||
for (it = caChannelList.begin(); it != caChannelList.end(); ++it)
|
||||
{
|
||||
CAChannelPtr caChannel(it->lock());
|
||||
if (caChannel)
|
||||
channelQ.push(caChannel);
|
||||
}
|
||||
caChannelList.clear();
|
||||
}
|
||||
while (!channelQ.empty())
|
||||
{
|
||||
channelQ.front()->disconnectChannel();
|
||||
channelQ.pop();
|
||||
epicsGuard<epicsMutex> G(channelListMutex);
|
||||
while (CAChannel *ch = caChannelList.first()) {
|
||||
ch->disconnectChannel(); // Removes itself from the list
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,18 +93,16 @@ Channel::shared_pointer CAChannelProvider::createChannel(
|
||||
return CAChannel::create(shared_from_this(), channelName, priority, channelRequester);
|
||||
}
|
||||
|
||||
void CAChannelProvider::addChannel(const CAChannelPtr &channel)
|
||||
void CAChannelProvider::addChannel(CAChannel &channel)
|
||||
{
|
||||
std::vector<CAChannelWPtr>::iterator it;
|
||||
epicsGuard<epicsMutex> G(channelListMutex);
|
||||
for (it = caChannelList.begin(); it != caChannelList.end(); ++it)
|
||||
{
|
||||
if (it->expired()) {
|
||||
*it = channel;
|
||||
return;
|
||||
}
|
||||
}
|
||||
caChannelList.push_back(channel);
|
||||
caChannelList.add(channel);
|
||||
}
|
||||
|
||||
void CAChannelProvider::delChannel(CAChannel &channel)
|
||||
{
|
||||
epicsGuard<epicsMutex> G(channelListMutex);
|
||||
caChannelList.remove(channel);
|
||||
}
|
||||
|
||||
void CAChannelProvider::configure(epics::pvData::PVStructure::shared_pointer /*configuration*/)
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include <cadef.h>
|
||||
#include <epicsMutex.h>
|
||||
#include <tsDLList.h>
|
||||
|
||||
#include <pv/logger.h>
|
||||
#include <pv/pvAccess.h>
|
||||
@ -80,7 +81,8 @@ public:
|
||||
virtual void flush();
|
||||
virtual void poll();
|
||||
|
||||
void addChannel(const CAChannelPtr & channel);
|
||||
void addChannel(CAChannel &channel);
|
||||
void delChannel(CAChannel &channel);
|
||||
|
||||
CAContextPtr caContext() {
|
||||
return ca_context;
|
||||
@ -94,7 +96,7 @@ public:
|
||||
private:
|
||||
CAContextPtr ca_context;
|
||||
epicsMutex channelListMutex;
|
||||
std::vector<CAChannelWPtr> caChannelList;
|
||||
tsDLList<CAChannel> caChannelList;
|
||||
|
||||
NotifierConveyor connectNotifier;
|
||||
NotifierConveyor resultNotifier;
|
||||
|
Reference in New Issue
Block a user