LimitedIo::StopReason LimitedIo::run(int nOpsLimit, const time::nanoseconds& timeLimit) { BOOST_ASSERT(!m_isRunning); if (nOpsLimit <= 0) { return EXCEED_OPS; } m_isRunning = true; m_reason = NO_WORK; m_nOpsRemaining = nOpsLimit; if (timeLimit >= time::nanoseconds::zero()) { m_timeout = scheduler::schedule(timeLimit, bind(&LimitedIo::afterTimeout, this)); } try { getGlobalIoService().run(); } catch (std::exception& ex) { m_reason = EXCEPTION; NFD_LOG_ERROR("g_io.run() exception: " << ex.what()); m_lastException = ex; } getGlobalIoService().reset(); scheduler::cancel(m_timeout); m_isRunning = false; return m_reason; }
explicit NfdRunner(const std::string& configFile) : m_nfd(configFile, m_nfdKeyChain) , m_configFile(configFile) , m_terminationSignalSet(getGlobalIoService()) , m_reloadSignalSet(getGlobalIoService()) { m_terminationSignalSet.add(SIGINT); m_terminationSignalSet.add(SIGTERM); m_terminationSignalSet.async_wait(bind(&NfdRunner::terminate, this, _1, _2)); m_reloadSignalSet.add(SIGHUP); m_reloadSignalSet.async_wait(bind(&NfdRunner::reload, this, _1, _2)); }
void LimitedIo::afterTimeout() { m_reason = EXCEED_TIME; getGlobalIoService().stop(); if (m_fixture != nullptr) { NDN_THROW(StopException()); } }
Scheduler& getGlobalScheduler() { if (g_scheduler.get() == nullptr) { g_scheduler.reset(new Scheduler(getGlobalIoService())); } return *g_scheduler; }
void terminate(const boost::system::error_code& error, int signalNo) { if (error) return; NFD_LOG_INFO("Caught signal '" << ::strsignal(signalNo) << "', exiting..."); getGlobalIoService().stop(); }
Resolver(const SuccessCallback& onSuccess, const ErrorCallback& onError, const nfd::resolver::AddressSelector& addressSelector) : m_resolver(getGlobalIoService()) , m_addressSelector(addressSelector) , m_onSuccess(onSuccess) , m_onError(onError) { }
LimitedIo::StopReason LimitedIo::run(int nOpsLimit, time::nanoseconds timeLimit, time::nanoseconds tick) { BOOST_ASSERT(!m_isRunning); if (nOpsLimit <= 0) { return EXCEED_OPS; } m_isRunning = true; m_reason = NO_WORK; m_nOpsRemaining = nOpsLimit; if (timeLimit >= 0_ns) { m_timeout = getScheduler().schedule(timeLimit, [this] { afterTimeout(); }); } try { if (m_fixture == nullptr) { getGlobalIoService().run(); } else { // timeLimit is enforced by afterTimeout m_fixture->advanceClocks(tick, time::nanoseconds::max()); } } catch (const StopException&) { } catch (...) { BOOST_WARN_MESSAGE(false, boost::current_exception_diagnostic_information()); m_reason = EXCEPTION; m_lastException = std::current_exception(); } getGlobalIoService().reset(); m_timeout.cancel(); m_isRunning = false; return m_reason; }
EthernetChannel::EthernetChannel(shared_ptr<const ndn::net::NetworkInterface> localEndpoint, time::nanoseconds idleTimeout) : m_localEndpoint(std::move(localEndpoint)) , m_isListening(false) , m_socket(getGlobalIoService()) , m_pcap(m_localEndpoint->getName()) , m_idleFaceTimeout(idleTimeout) #ifdef _DEBUG , m_nDropped(0) #endif { setUri(FaceUri::fromDev(m_localEndpoint->getName())); NFD_LOG_CHAN_INFO("Creating channel"); }
void TcpTransport::handleReconnectTimeout() { // abort the reconnection attempt boost::system::error_code error; m_socket.close(error); // exponentially back off the reconnection timer m_nextReconnectWait = std::min(time::duration_cast<time::milliseconds>(m_nextReconnectWait * s_reconnectWaitMultiplier), s_maxReconnectWait); // do this asynchronously because there could be some callbacks still pending getGlobalIoService().post([this] { reconnect(); }); }
void LimitedIo::afterOp() { if (!m_isRunning) { // Do not proceed further if .afterOp() is invoked out of .run(), // because io_service.stop() without io_service.reset() would leave it unusable. return; } --m_nOpsRemaining; if (m_nOpsRemaining <= 0) { m_reason = EXCEED_OPS; getGlobalIoService().stop(); } }
void TcpTransport::handleError(const boost::system::error_code& error) { if (this->getPersistency() == ndn::nfd::FACE_PERSISTENCY_PERMANENT) { NFD_LOG_FACE_TRACE("TCP socket error: " << error.message()); this->setState(TransportState::DOWN); // cancel all outstanding operations boost::system::error_code error; m_socket.cancel(error); // do this asynchronously because there could be some callbacks still pending getGlobalIoService().post([this] { reconnect(); }); } else { StreamTransport::handleError(error); } }
void LimitedIo::afterOp() { if (!m_isRunning) { // Do not proceed further if .afterOp() is invoked out of .run(), return; } --m_nOpsRemaining; if (m_nOpsRemaining <= 0) { m_reason = EXCEED_OPS; getGlobalIoService().stop(); if (m_fixture != nullptr) { NDN_THROW(StopException()); } } }
FaceManagerCommandNode::FaceManagerCommandNode(ndn::KeyChain& keyChain, uint16_t port) : face(getGlobalIoService(), keyChain, {true, true}) , dispatcher(face, keyChain, ndn::security::SigningInfo()) , authenticator(CommandAuthenticator::create()) , faceSystem(faceTable, make_shared<ndn::net::NetworkMonitorStub>(0)) , manager(faceSystem, dispatcher, *authenticator) { dispatcher.addTopPrefix("/localhost/nfd"); const std::string config = "face_system\n" "{\n" " tcp\n" " {\n" " port " + to_string(port) + "\n" " }\n" " udp\n" " {\n" " port " + to_string(port) + "\n" " mcast no\n" " }\n" " ether\n" " {\n" " mcast no\n" " }\n" "}\n" "authorizations\n" "{\n" " authorize\n" " {\n" " certfile any\n" " privileges\n" " {\n" " faces\n" " }\n" " }\n" "}\n" "\n"; ConfigFile cf; faceSystem.setConfigFile(cf); authenticator->setConfigFile(cf); cf.parse(config, false, "dummy-config"); }
void DatagramTransport<T, U>::doClose() { NFD_LOG_FACE_TRACE(__func__); if (m_socket.is_open()) { // Cancel all outstanding operations and close the socket. // Use the non-throwing variants and ignore errors, if any. boost::system::error_code error; m_socket.cancel(error); m_socket.close(error); } // Ensure that the Transport stays alive at least until // all pending handlers are dispatched getGlobalIoService().post([this] { this->setState(TransportState::CLOSED); }); }
shared_ptr<EthernetFace> EthernetFactory::createMulticastFace(const NetworkInterfaceInfo& interface, const ethernet::Address &address) { if (!address.isMulticast()) throw Error(address.toString() + " is not a multicast address"); shared_ptr<EthernetFace> face = findMulticastFace(interface.name, address); if (face) return face; auto socket = make_shared<boost::asio::posix::stream_descriptor>(ref(getGlobalIoService())); face = make_shared<EthernetFace>(socket, interface, address); auto key = std::make_pair(interface.name, address); face->onFail += [this, key] (const std::string& reason) { m_multicastFaces.erase(key); }; m_multicastFaces.insert({key, face}); return face; }
void Nrd::initialize() { m_face.reset(new ndn::Face(getLocalNfdTransport(), getGlobalIoService(), m_keyChain)); initializeLogging(); m_ribManager.reset(new RibManager(*m_face, m_keyChain)); ConfigFile config([] (const std::string& filename, const std::string& sectionName, const ConfigSection& section, bool isDryRun) { // Ignore "log" and sections belonging to NFD, // but raise an error if we're missing a handler for a "rib" section. if (sectionName != "rib" || sectionName == "log") { // do nothing } else { // missing NRD section ConfigFile::throwErrorOnUnknownSection(filename, sectionName, section, isDryRun); } }); m_ribManager->setConfigFile(config); // parse config file if (!m_configFile.empty()) { config.parse(m_configFile, true); config.parse(m_configFile, false); } else { config.parse(m_configSection, true, INTERNAL_CONFIG); config.parse(m_configSection, false, INTERNAL_CONFIG); } m_ribManager->registerWithNfd(); m_ribManager->enableLocalControlHeader(); }
Nfd::Nfd(ndn::KeyChain& keyChain) : m_keyChain(keyChain) , m_netmon(make_shared<ndn::net::NetworkMonitor>(getGlobalIoService())) { }
BaseFixture() : g_io(getGlobalIoService()) { }
void LimitedIo::afterTimeout() { m_reason = EXCEED_TIME; getGlobalIoService().stop(); }
int run() { /** \brief return value * A non-zero value is assigned when either NFD or RIB manager (running in a separate * thread) fails. */ std::atomic_int retval(0); boost::asio::io_service* const mainIo = &getGlobalIoService(); boost::asio::io_service* nrdIo = nullptr; // Mutex and conditional variable to implement synchronization between main and RIB manager // threads: // - to block main thread until RIB manager thread starts and initializes nrdIo (to allow // stopping it later) std::mutex m; std::condition_variable cv; std::string configFile = this->m_configFile; // c++11 lambda cannot capture member variables boost::thread nrdThread([configFile, &retval, &nrdIo, mainIo, &cv, &m] { { std::lock_guard<std::mutex> lock(m); nrdIo = &getGlobalIoService(); BOOST_ASSERT(nrdIo != mainIo); } cv.notify_all(); // notify that nrdIo has been assigned try { ndn::KeyChain nrdKeyChain; // must be created inside a separate thread rib::Nrd nrd(configFile, nrdKeyChain); nrd.initialize(); getGlobalIoService().run(); // nrdIo is not thread-safe to use here } catch (const std::exception& e) { NFD_LOG_FATAL(e.what()); retval = 6; mainIo->stop(); } { std::lock_guard<std::mutex> lock(m); nrdIo = nullptr; } }); { // Wait to guarantee that nrdIo is properly initialized, so it can be used to terminate // RIB manager thread. std::unique_lock<std::mutex> lock(m); cv.wait(lock, [&nrdIo] { return nrdIo != nullptr; }); } try { mainIo->run(); } catch (const std::exception& e) { NFD_LOG_FATAL(e.what()); retval = 4; } catch (const PrivilegeHelper::Error& e) { NFD_LOG_FATAL(e.what()); retval = 5; } { // nrdIo is guaranteed to be alive at this point std::lock_guard<std::mutex> lock(m); if (nrdIo != nullptr) { nrdIo->stop(); nrdIo = nullptr; } } nrdThread.join(); return retval; }