mirror of
https://github.com/Icinga/icinga2.git
synced 2025-07-25 22:54:57 +02:00
Merge pull request #8308 from Icinga/bugfix/configsyncstagelock-unlock-owner
Make ApiListener::m_ConfigSyncStageLock a SpinLock
This commit is contained in:
commit
21b30322c9
@ -63,6 +63,7 @@ set(base_SOURCES
|
||||
shared.hpp
|
||||
singleton.hpp
|
||||
socket.cpp socket.hpp
|
||||
spinlock.cpp spinlock.hpp
|
||||
stacktrace.cpp stacktrace.hpp
|
||||
statsfunction.hpp
|
||||
stdiostream.cpp stdiostream.hpp
|
||||
|
22
lib/base/spinlock.cpp
Normal file
22
lib/base/spinlock.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
/* Icinga 2 | (c) 2020 Icinga GmbH | GPLv2+ */
|
||||
|
||||
#include "base/spinlock.hpp"
|
||||
#include <atomic>
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
void SpinLock::lock()
|
||||
{
|
||||
while (m_Locked.test_and_set(std::memory_order_acquire)) {
|
||||
}
|
||||
}
|
||||
|
||||
bool SpinLock::try_lock()
|
||||
{
|
||||
return !m_Locked.test_and_set(std::memory_order_acquire);
|
||||
}
|
||||
|
||||
void SpinLock::unlock()
|
||||
{
|
||||
m_Locked.clear(std::memory_order_release);
|
||||
}
|
35
lib/base/spinlock.hpp
Normal file
35
lib/base/spinlock.hpp
Normal file
@ -0,0 +1,35 @@
|
||||
/* Icinga 2 | (c) 2020 Icinga GmbH | GPLv2+ */
|
||||
|
||||
#ifndef SPINLOCK_H
|
||||
#define SPINLOCK_H
|
||||
|
||||
#include <atomic>
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
||||
/**
|
||||
* A spin lock.
|
||||
*
|
||||
* @ingroup base
|
||||
*/
|
||||
class SpinLock
|
||||
{
|
||||
public:
|
||||
SpinLock() = default;
|
||||
SpinLock(const SpinLock&) = delete;
|
||||
SpinLock& operator=(const SpinLock&) = delete;
|
||||
SpinLock(SpinLock&&) = delete;
|
||||
SpinLock& operator=(SpinLock&&) = delete;
|
||||
|
||||
void lock();
|
||||
bool try_lock();
|
||||
void unlock();
|
||||
|
||||
private:
|
||||
std::atomic_flag m_Locked = ATOMIC_FLAG_INIT;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* SPINLOCK_H */
|
@ -20,7 +20,7 @@ using namespace icinga;
|
||||
|
||||
REGISTER_APIFUNCTION(Update, config, &ApiListener::ConfigUpdateHandler);
|
||||
|
||||
boost::mutex ApiListener::m_ConfigSyncStageLock;
|
||||
SpinLock ApiListener::m_ConfigSyncStageLock;
|
||||
|
||||
/**
|
||||
* Entrypoint for updating all authoritative configs from /etc/zones.d, packages, etc.
|
||||
@ -321,7 +321,7 @@ void ApiListener::HandleConfigUpdate(const MessageOrigin::Ptr& origin, const Dic
|
||||
/* Only one transaction is allowed, concurrent message handlers need to wait.
|
||||
* This affects two parent endpoints sending the config in the same moment.
|
||||
*/
|
||||
auto lock (Shared<boost::mutex::scoped_lock>::Make(m_ConfigSyncStageLock));
|
||||
auto lock (Shared<std::unique_lock<SpinLock>>::Make(m_ConfigSyncStageLock));
|
||||
|
||||
String apiZonesStageDir = GetApiZonesStageDir();
|
||||
String fromEndpointName = origin->FromClient->GetEndpoint()->GetName();
|
||||
@ -619,7 +619,7 @@ void ApiListener::TryActivateZonesStageCallback(const ProcessResult& pr,
|
||||
*
|
||||
* @param relativePaths Required for later file operations in the callback. Provides the zone name plus path in a list.
|
||||
*/
|
||||
void ApiListener::AsyncTryActivateZonesStage(const std::vector<String>& relativePaths, const Shared<boost::mutex::scoped_lock>::Ptr& lock)
|
||||
void ApiListener::AsyncTryActivateZonesStage(const std::vector<String>& relativePaths, const Shared<std::unique_lock<SpinLock>>::Ptr& lock)
|
||||
{
|
||||
VERIFY(Application::GetArgC() >= 1);
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "base/configobject.hpp"
|
||||
#include "base/process.hpp"
|
||||
#include "base/shared.hpp"
|
||||
#include "base/spinlock.hpp"
|
||||
#include "base/timer.hpp"
|
||||
#include "base/workqueue.hpp"
|
||||
#include "base/tcpsocket.hpp"
|
||||
@ -21,6 +22,7 @@
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/spawn.hpp>
|
||||
#include <boost/asio/ssl/context.hpp>
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
|
||||
namespace icinga
|
||||
@ -186,7 +188,7 @@ private:
|
||||
void RemoveStatusFile();
|
||||
|
||||
/* filesync */
|
||||
static boost::mutex m_ConfigSyncStageLock;
|
||||
static SpinLock m_ConfigSyncStageLock;
|
||||
|
||||
void SyncLocalZoneDirs() const;
|
||||
void SyncLocalZoneDir(const Zone::Ptr& zone) const;
|
||||
@ -200,7 +202,7 @@ private:
|
||||
|
||||
static void TryActivateZonesStageCallback(const ProcessResult& pr,
|
||||
const std::vector<String>& relativePaths);
|
||||
static void AsyncTryActivateZonesStage(const std::vector<String>& relativePaths, const Shared<boost::mutex::scoped_lock>::Ptr& lock);
|
||||
static void AsyncTryActivateZonesStage(const std::vector<String>& relativePaths, const Shared<std::unique_lock<SpinLock>>::Ptr& lock);
|
||||
|
||||
static String GetChecksum(const String& content);
|
||||
static bool CheckConfigChange(const ConfigDirInformation& oldConfig, const ConfigDirInformation& newConfig);
|
||||
|
Loading…
x
Reference in New Issue
Block a user