added startPVAServer() and 4.3 versions

This commit is contained in:
Matej Sekoranja
2013-06-10 12:10:38 +02:00
parent 3fd682d412
commit 54383923af
6 changed files with 125 additions and 13 deletions

View File

@@ -68,6 +68,9 @@ namespace pvAccess {
/** Default PVA provider name. */
const epics::pvData::String PVACCESS_DEFAULT_PROVIDER = "local";
/** "All-providers registered" PVA provider name. */
const epics::pvData::String PVACCESS_ALL_PROVIDERS = "<all>";
/** Name of the system env. variable to turn on debugging. */
const epics::pvData::String PVACCESS_DEBUG = "EPICS_PVA_DEBUG";
}

View File

@@ -3991,7 +3991,7 @@ namespace epics {
m_addressList(""), m_autoAddressList(true), m_connectionTimeout(30.0f), m_beaconPeriod(15.0f),
m_broadcastPort(PVA_BROADCAST_PORT), m_receiveBufferSize(MAX_TCP_RECV),
m_namedLocker(), m_lastCID(0), m_lastIOID(0),
m_version("pvAccess Client", "cpp", 1, 2, 0, true),
m_version("pvAccess Client", "cpp", 4, 3, 0, false),
m_contextState(CONTEXT_NOT_INITIALIZED),
m_configuration(new SystemConfigurationImpl()),
m_flushStrategy(DELAYED)

View File

@@ -18,7 +18,7 @@ using std::tr1::static_pointer_cast;
namespace epics { namespace pvAccess {
const char* ServerContextImpl::StateNames[] = { "NOT_INITIALIZED", "INITIALIZED", "RUNNING", "SHUTDOWN", "DESTROYED"};
const Version ServerContextImpl::VERSION("pvAccess Server", "cpp", 1, 2, 0, true);
const Version ServerContextImpl::VERSION("pvAccess Server", "cpp", 4, 3, 0, false);
ServerContextImpl::ServerContextImpl():
_state(NOT_INITIALIZED),
@@ -118,6 +118,12 @@ void ServerContextImpl::loadConfiguration()
_channelProviderNames = config->getPropertyAsString("EPICS_PVAS_PROVIDER_NAMES", _channelProviderNames);
}
bool ServerContextImpl::isChannelProviderNamePreconfigured()
{
Configuration::shared_pointer config = getConfiguration();
return config->hasProperty("EPICS_PVA_PROVIDER_NAMES") || config->hasProperty("EPICS_PVAS_PROVIDER_NAMES");
}
void ServerContextImpl::initialize(ChannelAccess::shared_pointer const & channelAccess)
{
Lock guard(_mutex);
@@ -138,13 +144,37 @@ void ServerContextImpl::initialize(ChannelAccess::shared_pointer const & channel
_channelAccess = channelAccess;
// split comma separated names
std::stringstream ss(_channelProviderNames);
std::string providerName;
while (std::getline(ss, providerName, ',')) {
ChannelProvider::shared_pointer channelProvider = _channelAccess->getProvider(providerName);
if (channelProvider)
_channelProviders.push_back(channelProvider);
// user all providers
if (_channelProviderNames == PVACCESS_ALL_PROVIDERS)
{
_channelProviderNames.clear();
std::auto_ptr<ChannelAccess::stringVector_t> names = _channelAccess->getProviderNames();
for (ChannelAccess::stringVector_t::iterator iter = names->begin(); iter != names->end(); iter++)
{
ChannelProvider::shared_pointer channelProvider = _channelAccess->getProvider(*iter);
if (channelProvider)
{
_channelProviders.push_back(channelProvider);
// compile a list
if (!_channelProviderNames.empty())
_channelProviderNames += ' ';
_channelProviderNames += *iter;
}
}
}
else
{
// split space separated names
std::stringstream ss(_channelProviderNames);
std::string providerName;
while (std::getline(ss, providerName, ' '))
{
ChannelProvider::shared_pointer channelProvider = _channelAccess->getProvider(providerName);
if (channelProvider)
_channelProviders.push_back(channelProvider);
}
}
//_channelProvider = _channelAccess->getProvider(_channelProviderNames);
@@ -564,5 +594,60 @@ void ServerContextImpl::newServerDetected()
}
struct ThreadRunnerParam {
ServerContextImpl::shared_pointer ctx;
int timeToRun;
};
static void threadRunner(void* usr)
{
ThreadRunnerParam* pusr = static_cast<ThreadRunnerParam*>(usr);
ThreadRunnerParam param = *pusr;
delete pusr;
param.ctx->run(param.timeToRun);
}
ServerContext::shared_pointer startPVAServer(String const & providerNames, int timeToRun, bool runInSeparateThread, bool printInfo)
{
ServerContextImpl::shared_pointer ctx = ServerContextImpl::create();
// do not override configuration
if (providerNames == PVACCESS_ALL_PROVIDERS && !ctx->isChannelProviderNamePreconfigured())
ctx->setChannelProviderName(providerNames);
ChannelAccess::shared_pointer channelAccess = getChannelAccess();
ctx->initialize(channelAccess);
if (printInfo)
ctx->printInfo();
if (runInSeparateThread)
{
// delete left to the thread
auto_ptr<ThreadRunnerParam> param(new ThreadRunnerParam());
param->ctx = ctx;
param->timeToRun = timeToRun;
// TODO can this fail?
epicsThreadCreate("startPVAServer",
epicsThreadPriorityMedium,
epicsThreadGetStackSize(epicsThreadStackBig),
threadRunner, param.get());
param.release();
}
else
{
ctx->run(timeToRun);
}
return ctx;
}
}
}

View File

@@ -39,7 +39,7 @@ public:
*/
virtual const Version& getVersion() = 0;
/**
/**
* Set <code>ChannelAccess</code> implementation and initialize server.
* @param channelAccess implementation of channel access to be served.
*/
@@ -114,7 +114,7 @@ public:
//**************** derived from ServerContext ****************//
const Version& getVersion();
void initialize(ChannelAccess::shared_pointer const & channelAccess);
void initialize(ChannelAccess::shared_pointer const & channelAccess);
void run(epics::pvData::int32 seconds);
void shutdown();
void destroy();
@@ -274,6 +274,12 @@ public:
*/
std::vector<ChannelProvider::shared_pointer> getChannelProviders();
/**
* Return <code>true</code> if channel provider name is provided by configuration (e.g. system env. var.).
* @return <code>true</code> if channel provider name is provided by configuration (e.g. system env. var.)
*/
bool isChannelProviderNamePreconfigured();
private:
/**
* Initialization status.
@@ -406,7 +412,11 @@ private:
Configuration::shared_pointer configuration;
};
extern ServerContext::shared_pointer startPVAServer(
epics::pvData::String const & providerNames = PVACCESS_ALL_PROVIDERS,
int timeToRun = 0,
bool runInSeparateThread = false,
bool printInfo = false);
}
}

View File

@@ -80,6 +80,11 @@ string Properties::getProperty(const string &key, const string &defaultValue)
return defaultValue;
}
bool Properties::hasProperty(const string &key)
{
return (_properties.find(key) != _properties.end());
}
void Properties::load()
{
_properties.clear();
@@ -333,6 +338,11 @@ string SystemConfigurationImpl::getPropertyAsString(const string &name, const st
return _properties->getProperty(name,defaultValue);
}
bool SystemConfigurationImpl::hasProperty(const string &key)
{
return _properties->hasProperty(key);
}
ConfigurationProviderImpl::ConfigurationProviderImpl()
{

View File

@@ -34,6 +34,7 @@ public:
void setProperty(const std::string &key,const std::string &value);
std::string getProperty(const std::string &key);
std::string getProperty(const std::string &key, const std::string &defaultValue);
bool hasProperty(const std::string &key);
void store();
void store(const std::string &fileName);
@@ -124,6 +125,8 @@ public:
* @return environment variable value as std::string or default value if it does not exist.
*/
virtual std::string getPropertyAsString(const std::string &name, const std::string &defaultValue) = 0;
virtual bool hasProperty(const std::string &name) = 0;
};
class SystemConfigurationImpl: public Configuration
@@ -136,7 +139,8 @@ public:
float getPropertyAsFloat(const std::string &name, const float defaultValue);
float getPropertyAsDouble(const std::string &name, const double defaultValue);
std::string getPropertyAsString(const std::string &name, const std::string &defaultValue);
std::auto_ptr<Properties> _properties;
bool hasProperty(const std::string &name);
std::auto_ptr<Properties> _properties;
private:
ENV_PARAM _envParam;
std::istringstream _ibuffer;