bool CSettingsManager::Load(const TiXmlElement *root, bool &updated, bool triggerEvents /* = true */, std::map<std::string, CSetting*> *loadedSettings /* = NULL */) { CSharedLock lock(m_critical); CExclusiveLock settingsLock(m_settingsCritical); if (m_loaded || root == NULL) return false; if (triggerEvents && !OnSettingsLoading()) return false; if (!Deserialize(root, loadedSettings)) return false; bool ret = true; // load any ISubSettings implementations if (triggerEvents) ret = Load(root); updated = UpdateSettings(root); if (triggerEvents) OnSettingsLoaded(); return ret; }
bool CSettingsManager::Save(TiXmlNode *root) const { CSharedLock lock(m_critical); CSharedLock settingsLock(m_settingsCritical); if (!m_initialized || root == NULL) return false; if (!OnSettingsSaving()) return false; if (!Serialize(root)) { CLog::Log(LOGERROR, "CSettingsManager: failed to save settings"); return false; } // save any ISubSettings implementations for (std::set<ISubSettings*>::const_iterator it = m_subSettings.begin(); it != m_subSettings.end(); ++it) { if (!(*it)->Save(root)) return false; } OnSettingsSaved(); return true; }
void TcpSocketServer::close() { std::lock_guard settingsLock(_settingsMutex); _listening = false; // Notify all threads waiting for connections. _connectionNotifier.notify_all(); const _SOCKET serverSocket = _serverSocket; _serverSocket = INVALID_SOCKET; closeSocket(serverSocket); _serverThread->join(); }
bool CSettingsManager::Initialize(const TiXmlElement *root) { CExclusiveLock lock(m_critical); CExclusiveLock settingsLock(m_settingsCritical); if (m_initialized || root == NULL) return false; if (!StringUtils::EqualsNoCase(root->ValueStr(), SETTING_XML_ROOT)) { CLog::Log(LOGERROR, "CSettingsManager: error reading settings definition: doesn't contain <settings> tag"); return false; } const TiXmlNode *sectionNode = root->FirstChild(SETTING_XML_ELM_SECTION); while (sectionNode != NULL) { std::string sectionId; if (CSettingSection::DeserializeIdentification(sectionNode, sectionId)) { CSettingSection *section = NULL; SettingSectionMap::iterator itSection = m_sections.find(sectionId); bool update = (itSection != m_sections.end()); if (!update) section = new CSettingSection(sectionId, this); else section = itSection->second; if (section->Deserialize(sectionNode, update)) AddSection(section); else { CLog::Log(LOGWARNING, "CSettingsManager: unable to read section \"%s\"", sectionId.c_str()); if (!update) delete section; } } sectionNode = sectionNode->NextSibling(SETTING_XML_ELM_SECTION); } return true; }
bool CSettingsManager::Initialize(const TiXmlElement *root) { CExclusiveLock lock(m_critical); CExclusiveLock settingsLock(m_settingsCritical); if (m_initialized || root == NULL) return false; if (!StringUtils::EqualsNoCase(root->ValueStr(), SETTING_XML_ROOT)) { CLog::Log(LOGERROR, "CSettingsManager: error reading settings definition: doesn't contain <settings> tag"); return false; } const TiXmlNode *sectionNode = root->FirstChild(SETTING_XML_ELM_SECTION); while (sectionNode != NULL) { std::string sectionId; if (CSettingSection::DeserializeIdentification(sectionNode, sectionId)) { CSettingSection *section = NULL; SettingSectionMap::iterator itSection = m_sections.find(sectionId); bool update = (itSection != m_sections.end()); if (!update) section = new CSettingSection(sectionId, this); else section = itSection->second; if (section->Deserialize(sectionNode, update)) { section->CheckRequirements(); if (!update) m_sections[section->GetId()] = section; // get all settings and add them to the settings map for (SettingCategoryList::const_iterator categoryIt = section->GetCategories().begin(); categoryIt != section->GetCategories().end(); ++categoryIt) { (*categoryIt)->CheckRequirements(); for (SettingGroupList::const_iterator groupIt = (*categoryIt)->GetGroups().begin(); groupIt != (*categoryIt)->GetGroups().end(); ++groupIt) { (*groupIt)->CheckRequirements(); for (SettingList::const_iterator settingIt = (*groupIt)->GetSettings().begin(); settingIt != (*groupIt)->GetSettings().end(); ++settingIt) { (*settingIt)->CheckRequirements(); const std::string &settingId = (*settingIt)->GetId(); SettingMap::iterator setting = m_settings.find(settingId); if (setting == m_settings.end()) { Setting tmpSetting = { NULL }; std::pair<SettingMap::iterator, bool> tmpIt = m_settings.insert(make_pair(settingId, tmpSetting)); setting = tmpIt.first; } if (setting->second.setting == NULL) { setting->second.setting = *settingIt; (*settingIt)->m_callback = this; } } } } } else { CLog::Log(LOGWARNING, "CSettingsManager: unable to read section \"%s\"", sectionId.c_str()); if (!update) delete section; } } sectionNode = sectionNode->NextSibling(SETTING_XML_ELM_SECTION); } for (SettingMap::iterator itSettingDep = m_settings.begin(); itSettingDep != m_settings.end(); ++itSettingDep) { if (itSettingDep->second.setting == NULL) continue; const SettingDependencies& deps = itSettingDep->second.setting->GetDependencies(); for (SettingDependencies::const_iterator depIt = deps.begin(); depIt != deps.end(); ++depIt) { std::set<std::string> settingIds = depIt->GetSettings(); for (std::set<std::string>::const_iterator itSettingId = settingIds.begin(); itSettingId != settingIds.end(); ++itSettingId) { SettingMap::iterator setting = m_settings.find(*itSettingId); if (setting == m_settings.end()) continue; bool newDep = true; SettingDependencies &settingDeps = setting->second.dependencies[itSettingDep->first]; for (SettingDependencies::const_iterator itDeps = settingDeps.begin(); itDeps != settingDeps.end(); ++itDeps) { if (itDeps->GetType() == depIt->GetType()) { newDep = false; break; } } if (newDep) settingDeps.push_back(*depIt); } } } return true; }
bool TcpSocketServer::isListening() const { std::lock_guard settingsLock(_settingsMutex); return _listening; }
void TcpSocketServer::listen(int port) { if (_listening) { throw TcpSocket::TcpSocketError("Socket is already listening."); } if (!TcpSocket::initializedNetworkApi()) { TcpSocket::initializeNetworkApi(); } std::lock_guard settingsLock(_settingsMutex); _port = port; struct addrinfo* result = nullptr; struct addrinfo hints {}; std::memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = AI_PASSIVE; int iResult; // Resolve the local address and port to be used by the server iResult = getaddrinfo(nullptr, std::to_string(_port).c_str(), &hints, &result); if (iResult != 0) { #if defined(WIN32) WSACleanup(); #endif throw TcpSocket::TcpSocketError("Failed to parse hints for connection!"); } // Create a socket for the server to listen for client connections _serverSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol); if (_serverSocket == INVALID_SOCKET) { freeaddrinfo(result); #if defined(WIN32) WSACleanup(); #endif throw TcpSocket::TcpSocketError("Failed to init server socket!"); } setOptions(_serverSocket); // Setup the TCP listening socket iResult = bind(_serverSocket, result->ai_addr, static_cast<int>(result->ai_addrlen)); if (iResult == SOCKET_ERROR) { freeaddrinfo(result); closeSocket(_serverSocket); #if defined(WIN32) WSACleanup(); #endif throw TcpSocket::TcpSocketError( "Bind failed with error: " + std::to_string(_ERRNO) ); } // Clean up freeaddrinfo(result); if (::listen(_serverSocket, SOMAXCONN) == SOCKET_ERROR) { closeSocket(_serverSocket); #if defined(WIN32) WSACleanup(); #endif TcpSocket::TcpSocketError("Listen failed with error: " + std::to_string(_ERRNO)); } _listening = true; _serverThread = std::make_unique<std::thread>([this]() { waitForConnections(); }); }
int TcpSocketServer::port() const { std::lock_guard settingsLock(_settingsMutex); return _port; }