@@ -251,7 +251,8 @@ CAChannel::CAChannel(std::string const & _channelName,
|
||||
channelRequester(_channelRequester),
|
||||
channelID(0),
|
||||
channelType(0),
|
||||
elementCount(0)
|
||||
elementCount(0),
|
||||
destroyed(false)
|
||||
{
|
||||
PVACCESS_REFCOUNT_MONITOR_CONSTRUCT(caChannel);
|
||||
}
|
||||
@@ -265,6 +266,8 @@ void CAChannel::activate(short priority)
|
||||
&channelID);
|
||||
if (result == ECA_NORMAL)
|
||||
{
|
||||
channelProvider->registerChannel(shared_from_this());
|
||||
|
||||
// TODO be sure that ca_connection_handler is not called before this call
|
||||
EXCEPTION_GUARD(channelRequester->channelCreated(Status::Ok, shared_from_this()));
|
||||
}
|
||||
@@ -278,6 +281,19 @@ void CAChannel::activate(short priority)
|
||||
CAChannel::~CAChannel()
|
||||
{
|
||||
PVACCESS_REFCOUNT_MONITOR_DESTRUCT(caChannel);
|
||||
|
||||
Lock lock(requestsMutex);
|
||||
{
|
||||
if (destroyed)
|
||||
return;
|
||||
destroyed = true;
|
||||
}
|
||||
|
||||
channelProvider->unregisterChannel(this);
|
||||
|
||||
/* Clear CA Channel */
|
||||
threadAttach();
|
||||
ca_clear_channel(channelID);
|
||||
}
|
||||
|
||||
|
||||
@@ -454,19 +470,24 @@ void CAChannel::printInfo(std::ostream& out)
|
||||
|
||||
void CAChannel::destroy()
|
||||
{
|
||||
threadAttach();
|
||||
|
||||
Lock lock(requestsMutex);
|
||||
{
|
||||
if (destroyed)
|
||||
return;
|
||||
destroyed = true;
|
||||
|
||||
while (!requests.empty())
|
||||
{
|
||||
ChannelRequest::shared_pointer request = requests.rbegin()->second.lock();
|
||||
ChannelRequest::shared_pointer request = requests.begin()->second.lock();
|
||||
if (request)
|
||||
request->destroy();
|
||||
}
|
||||
}
|
||||
|
||||
channelProvider->unregisterChannel(shared_from_this());
|
||||
|
||||
/* Clear CA Channel */
|
||||
threadAttach();
|
||||
ca_clear_channel(channelID);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,13 +25,15 @@ using namespace epics::pvAccess::ca;
|
||||
|
||||
std::string CAChannelProvider::PROVIDER_NAME = "ca";
|
||||
|
||||
CAChannelProvider::CAChannelProvider() : current_context(0)
|
||||
CAChannelProvider::CAChannelProvider() : current_context(0), destroyed(false)
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
|
||||
CAChannelProvider::~CAChannelProvider()
|
||||
{
|
||||
// call destroy() to destroy CA context
|
||||
destroy();
|
||||
}
|
||||
|
||||
std::string CAChannelProvider::getProviderName()
|
||||
@@ -107,11 +109,17 @@ void CAChannelProvider::destroy()
|
||||
{
|
||||
Lock lock(channelsMutex);
|
||||
{
|
||||
if (destroyed)
|
||||
return;
|
||||
destroyed = true;
|
||||
|
||||
while (!channels.empty())
|
||||
{
|
||||
Channel::shared_pointer channel = channels.rbegin()->second.lock();
|
||||
Channel::shared_pointer channel = channels.begin()->second.lock();
|
||||
if (channel)
|
||||
channel->destroy();
|
||||
else
|
||||
channels.erase(channels.begin());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,6 +144,12 @@ void CAChannelProvider::unregisterChannel(Channel::shared_pointer const & channe
|
||||
channels.erase(channel.get());
|
||||
}
|
||||
|
||||
void CAChannelProvider::unregisterChannel(Channel* pchannel)
|
||||
{
|
||||
Lock lock(channelsMutex);
|
||||
channels.erase(pchannel);
|
||||
}
|
||||
|
||||
void CAChannelProvider::initialize()
|
||||
{
|
||||
/* Create Channel Access */
|
||||
|
||||
@@ -112,9 +112,12 @@ private:
|
||||
|
||||
epics::pvData::Mutex requestsMutex;
|
||||
// TODO std::unordered_map
|
||||
// void* is not the nicest thing, but there is no fast weak_ptr==
|
||||
// void* is not the nicest thing, but there is no fast weak_ptr::operator==
|
||||
typedef std::map<void*, ChannelRequest::weak_pointer> RequestsList;
|
||||
RequestsList requests;
|
||||
|
||||
// synced on requestsMutex
|
||||
bool destroyed;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ class epicsShareClass CAChannelProvider :
|
||||
public std::tr1::enable_shared_from_this<CAChannelProvider>
|
||||
{
|
||||
public:
|
||||
POINTER_DEFINITIONS(CAChannelProvider);
|
||||
|
||||
static std::string PROVIDER_NAME;
|
||||
|
||||
@@ -63,6 +64,7 @@ public:
|
||||
|
||||
void registerChannel(Channel::shared_pointer const & channel);
|
||||
void unregisterChannel(Channel::shared_pointer const & channel);
|
||||
void unregisterChannel(Channel* pchannel);
|
||||
|
||||
private:
|
||||
|
||||
@@ -72,9 +74,12 @@ private:
|
||||
|
||||
epics::pvData::Mutex channelsMutex;
|
||||
// TODO std::unordered_map
|
||||
// void* is not the nicest thing, but there is no fast weak_ptr==
|
||||
// void* is not the nicest thing, but there is no fast weak_ptr::operator==
|
||||
typedef std::map<void*, Channel::weak_pointer> ChannelList;
|
||||
ChannelList channels;
|
||||
|
||||
// synced on channelsMutex
|
||||
bool destroyed;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user