more changes to pull from epics-base

This commit is contained in:
mrkraimer
2017-07-21 09:41:15 -04:00
parent 01b0b821e4
commit f7874396b9
3 changed files with 3 additions and 117 deletions

View File

@@ -1,99 +0,0 @@
========
Overview
========
pvaCientCPP did not terminate properly.
It has a singleton class named **PvaClient**.
When the singleton is created it calls:
ClientFactory::start();
The destructor for **PvaClient** calls:
ClientFactory::stop();
This call results in the following message:
terminate called after throwing an instance of 'epicsMutex::invalidMutex'
what(): epicsMutex::invalidMutex()
Further investigation found that this was caused by a mutex belonging to ChannelProviderRegistry.
If fact it appeared that the only way the crash did not occur is if the client code was of the form:
int main(int argc,char *argv[])
{
ClientFactory::start();
...
ClientFactory::stop();
}
While investigating this problem I also realized that the existing implementation of
ClientFactory only worked if a single call was made to start and a single call to stop.
In pvAccessCPP changes were made to the followimg:
1) ChannelProviderRegistry
2) ClientFactory
3) CAChannelProviderFactory
These are discussed below.
Changes were also made to pvaClientCPP.
The change was to use the new ChannelProviderRegistry methods.
All these changes are in the github repositories belonging to mrkraimer.
-----------------------
ChannelProviderRegistry
-----------------------
The following new method is added to ChannelProviderRegistry:
static ChannelProviderRegistry::shared_pointer getChannelProviderRegistry();
**getChannelProviderRegistry** creates the single instance of **ChannelProviderRegistry**
the first time it is called and always returns a shared pointer to the single
instance,
Any facility that calls the start/stop methods of any channelProvider factory must keep the shared pointer
until the facility no longer requires use of the registry or any channel provider the facility uses.
The above methods replace the following functions:
// THE FOLLOWING SHOULD NOT BE CALLED
epicsShareFunc ChannelProviderRegistry::shared_pointer getChannelProviderRegistry() EPICS_DEPRECATED;
epicsShareFunc void registerChannelProviderFactory(
ChannelProviderFactory::shared_pointer const & channelProviderFactory) EPICS_DEPRECATED;
epicsShareFunc void unregisterChannelProviderFactory(
ChannelProviderFactory::shared_pointer const & channelProviderFactory) EPICS_DEPRECATED;
epicsShareFunc void unregisterAllChannelProviderFactory() EPICS_DEPRECATED;
Note that the methods are all deprecated.
They were kept so that existing code will still compile and run.
Any code that uses these methods may see the invalidMutex exception on termination.
-------------
ClientFactory
-------------
This has two major changes:
1) It uses the new **ChannelProviderRegistry** methods,
2) It allows multiple calls to start and stop.
------------------------
CAChannelProviderFactory
------------------------
This has two major changes:
1) It uses the new **ChannelProviderRegistry** methods,
2) It allows multiple calls to start and stop.

View File

@@ -20,7 +20,7 @@ class Configuration;
namespace ca {
class epicsShareClass CAChannelProvider :
public epics::pvAccess::ChannelProvider,
public ChannelProvider,
public std::tr1::enable_shared_from_this<CAChannelProvider>
{
public:
@@ -83,11 +83,8 @@ private:
};
class epicsShareClass CAClientFactory {
private:
static epics::pvAccess::ChannelProviderRegistry::shared_pointer channelRegistry;
static epics::pvAccess::ChannelProviderFactory::shared_pointer channelProvider;
static int numStart;
class epicsShareClass CAClientFactory
{
public:
static void start();
static void stop();

View File

@@ -9,22 +9,10 @@
#include <shareLib.h>
#include <pv/sharedPtr.h>
namespace epics {
namespace pvAccess {
class ChannelProviderRegistry;
typedef std::tr1::shared_ptr<ChannelProviderRegistry> ChannelProviderRegistryPtr;
class ChannelProviderFactory;
typedef std::tr1::shared_ptr<ChannelProviderFactory> ChannelProviderFactoryPtr;
class epicsShareClass ClientFactory {
private:
static ChannelProviderRegistryPtr channelRegistry;
static ChannelProviderFactoryPtr channelProvider;
static int numStart;
public:
static void start();
static void stop();