rib: make Service globally accessible via get() static function
Change-Id: I2101fb81a613d301acbce7f26e062caa692c5e29
Refs: #4683
diff --git a/rib/service.cpp b/rib/service.cpp
index dce806f..de103b4 100644
--- a/rib/service.cpp
+++ b/rib/service.cpp
@@ -37,22 +37,50 @@
static const std::string INTERNAL_CONFIG = "internal://nfd.conf";
+Service* Service::s_instance = nullptr;
+
Service::Service(const std::string& configFile, ndn::KeyChain& keyChain)
: m_configFile(configFile)
, m_keyChain(keyChain)
{
+ if (s_instance != nullptr) {
+ BOOST_THROW_EXCEPTION(std::logic_error("RIB service cannot be instantiated more than once"));
+ }
+ if (&getGlobalIoService() != &getRibIoService()) {
+ BOOST_THROW_EXCEPTION(std::logic_error("RIB service must run on RIB thread"));
+ }
+ s_instance = this;
}
Service::Service(const ConfigSection& config, ndn::KeyChain& keyChain)
: m_configSection(config)
, m_keyChain(keyChain)
{
+ if (s_instance != nullptr) {
+ BOOST_THROW_EXCEPTION(std::logic_error("RIB service cannot be instantiated more than once"));
+ }
+ if (&getGlobalIoService() != &getRibIoService()) {
+ BOOST_THROW_EXCEPTION(std::logic_error("RIB service must run on RIB thread"));
+ }
+ s_instance = this;
}
-// It is necessary to explicitly define the destructor, because some member variables
-// (e.g., unique_ptr<RibManager>) are forward-declared, but implicitly declared destructor
-// requires complete types for all members when instantiated.
-Service::~Service() = default;
+Service::~Service()
+{
+ s_instance = nullptr;
+}
+
+Service&
+Service::get()
+{
+ if (s_instance == nullptr) {
+ BOOST_THROW_EXCEPTION(std::logic_error("RIB service is not instantiated"));
+ }
+ if (&getGlobalIoService() != &getRibIoService()) {
+ BOOST_THROW_EXCEPTION(std::logic_error("Must get RIB service on RIB thread"));
+ }
+ return *s_instance;
+}
void
Service::initialize()
diff --git a/rib/service.hpp b/rib/service.hpp
index 35223dc..6c01f3e 100644
--- a/rib/service.hpp
+++ b/rib/service.hpp
@@ -40,6 +40,8 @@
/**
* \brief initializes and executes NFD-RIB service thread
+ *
+ * Only one instance of this class can be created at any time
*/
class Service : noncopyable
{
@@ -58,6 +60,8 @@
* \brief create NFD-RIB service
* \param configFile absolute or relative path of configuration file
* \param keyChain the KeyChain
+ * \throw std::logic_error Instance of rib::Service has been already constructed
+ * \throw std::logic_error Instance of rib::Service is not constructed on RIB thread
*/
Service(const std::string& configFile, ndn::KeyChain& keyChain);
@@ -68,6 +72,8 @@
* \note This constructor overload is more appropriate for integrated environments,
* such as NS-3 or android. Error messages related to configuration file
* will use "internal://nfd.conf" as configuration filename.
+ * \throw std::logic_error Instance of rib::Service has been already constructed
+ * \throw std::logic_error Instance of rib::Service is not constructed on RIB thread
*/
Service(const ConfigSection& config, ndn::KeyChain& keyChain);
@@ -84,6 +90,14 @@
void
initialize();
+ /**
+ * \brief Get a reference to the only instance of this class
+ * \throw std::logic_error No instance has been constructed
+ * \throw std::logic_error This function is invoked on a thread other than the RIB thread
+ */
+ static Service&
+ get();
+
private:
/**
* \brief Look into the config file and construct appropriate transport to communicate with NFD
@@ -93,6 +107,8 @@
getLocalNfdTransport();
private:
+ static Service* s_instance;
+
std::string m_configFile;
ConfigSection m_configSection;