mirror of
https://github.com/Icinga/icinga2.git
synced 2026-02-18 18:19:13 -05:00
Merge pull request #10388 from Icinga/Registry-Freeze
Some checks failed
Container Image / Container Image (push) Has been cancelled
Linux / alpine:bash (push) Has been cancelled
Linux / amazonlinux:2 (push) Has been cancelled
Linux / amazonlinux:2023 (push) Has been cancelled
Linux / debian:11 (linux/386) (push) Has been cancelled
Linux / debian:11 (push) Has been cancelled
Linux / debian:12 (linux/386) (push) Has been cancelled
Linux / debian:12 (push) Has been cancelled
Linux / debian:13 (push) Has been cancelled
Linux / fedora:41 (push) Has been cancelled
Linux / fedora:42 (push) Has been cancelled
Linux / fedora:43 (push) Has been cancelled
Linux / opensuse/leap:15.6 (push) Has been cancelled
Linux / opensuse/leap:16.0 (push) Has been cancelled
Linux / registry.suse.com/bci/bci-base:16.0 (push) Has been cancelled
Linux / registry.suse.com/suse/sle15:15.6 (push) Has been cancelled
Linux / registry.suse.com/suse/sle15:15.7 (push) Has been cancelled
Linux / rockylinux/rockylinux:10 (push) Has been cancelled
Linux / rockylinux:8 (push) Has been cancelled
Linux / rockylinux:9 (push) Has been cancelled
Linux / ubuntu:22.04 (push) Has been cancelled
Linux / ubuntu:24.04 (push) Has been cancelled
Linux / ubuntu:25.04 (push) Has been cancelled
Linux / ubuntu:25.10 (push) Has been cancelled
Windows / Windows (push) Has been cancelled
Some checks failed
Container Image / Container Image (push) Has been cancelled
Linux / alpine:bash (push) Has been cancelled
Linux / amazonlinux:2 (push) Has been cancelled
Linux / amazonlinux:2023 (push) Has been cancelled
Linux / debian:11 (linux/386) (push) Has been cancelled
Linux / debian:11 (push) Has been cancelled
Linux / debian:12 (linux/386) (push) Has been cancelled
Linux / debian:12 (push) Has been cancelled
Linux / debian:13 (push) Has been cancelled
Linux / fedora:41 (push) Has been cancelled
Linux / fedora:42 (push) Has been cancelled
Linux / fedora:43 (push) Has been cancelled
Linux / opensuse/leap:15.6 (push) Has been cancelled
Linux / opensuse/leap:16.0 (push) Has been cancelled
Linux / registry.suse.com/bci/bci-base:16.0 (push) Has been cancelled
Linux / registry.suse.com/suse/sle15:15.6 (push) Has been cancelled
Linux / registry.suse.com/suse/sle15:15.7 (push) Has been cancelled
Linux / rockylinux/rockylinux:10 (push) Has been cancelled
Linux / rockylinux:8 (push) Has been cancelled
Linux / rockylinux:9 (push) Has been cancelled
Linux / ubuntu:22.04 (push) Has been cancelled
Linux / ubuntu:24.04 (push) Has been cancelled
Linux / ubuntu:25.04 (push) Has been cancelled
Linux / ubuntu:25.10 (push) Has been cancelled
Windows / Windows (push) Has been cancelled
Freeze registries at startup, when everything has been registered
This commit is contained in:
commit
9bffe06169
9 changed files with 52 additions and 75 deletions
|
|
@ -4,9 +4,13 @@
|
|||
#define REGISTRY_H
|
||||
|
||||
#include "base/i2-base.hpp"
|
||||
#include "base/atomic.hpp"
|
||||
#include "base/exception.hpp"
|
||||
#include "base/string.hpp"
|
||||
#include <boost/signals2.hpp>
|
||||
#include <map>
|
||||
#include "base/singleton.hpp"
|
||||
#include <shared_mutex>
|
||||
#include <stdexcept>
|
||||
#include <unordered_map>
|
||||
#include <mutex>
|
||||
|
||||
namespace icinga
|
||||
|
|
@ -17,22 +21,31 @@ namespace icinga
|
|||
*
|
||||
* @ingroup base
|
||||
*/
|
||||
template<typename U, typename T>
|
||||
template<typename T>
|
||||
class Registry
|
||||
{
|
||||
public:
|
||||
typedef std::map<String, T> ItemMap;
|
||||
typedef std::unordered_map<String, T> ItemMap;
|
||||
|
||||
static Registry* GetInstance()
|
||||
{
|
||||
return Singleton<Registry>::GetInstance();
|
||||
}
|
||||
|
||||
void Register(const String& name, const T& item)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_Mutex);
|
||||
std::unique_lock lock (m_Mutex);
|
||||
|
||||
RegisterInternal(name, item, lock);
|
||||
if (m_Frozen) {
|
||||
BOOST_THROW_EXCEPTION(std::logic_error("Registry is read-only and must not be modified."));
|
||||
}
|
||||
|
||||
m_Items[name] = item;
|
||||
}
|
||||
|
||||
T GetItem(const String& name) const
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_Mutex);
|
||||
auto lock (ReadLockUnlessFrozen());
|
||||
|
||||
auto it = m_Items.find(name);
|
||||
|
||||
|
|
@ -44,33 +57,36 @@ public:
|
|||
|
||||
ItemMap GetItems() const
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_Mutex);
|
||||
auto lock (ReadLockUnlessFrozen());
|
||||
|
||||
return m_Items; /* Makes a copy of the map. */
|
||||
}
|
||||
|
||||
boost::signals2::signal<void (const String&, const T&)> OnRegistered;
|
||||
boost::signals2::signal<void (const String&)> OnUnregistered;
|
||||
/**
|
||||
* Freeze the registry, preventing further updates.
|
||||
*
|
||||
* This only prevents inserting, replacing or deleting values from the registry.
|
||||
* This operation has no effect on objects referenced by the values, these remain mutable if they were before.
|
||||
*/
|
||||
void Freeze()
|
||||
{
|
||||
std::unique_lock lock (m_Mutex);
|
||||
|
||||
m_Frozen.store(true);
|
||||
}
|
||||
|
||||
private:
|
||||
mutable std::mutex m_Mutex;
|
||||
typename Registry<U, T>::ItemMap m_Items;
|
||||
mutable std::shared_mutex m_Mutex;
|
||||
Atomic<bool> m_Frozen {false};
|
||||
ItemMap m_Items;
|
||||
|
||||
void RegisterInternal(const String& name, const T& item, std::unique_lock<std::mutex>& lock)
|
||||
std::shared_lock<std::shared_mutex> ReadLockUnlessFrozen() const
|
||||
{
|
||||
bool old_item = false;
|
||||
if (m_Frozen.load(std::memory_order_relaxed)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
if (m_Items.erase(name) > 0)
|
||||
old_item = true;
|
||||
|
||||
m_Items[name] = item;
|
||||
|
||||
lock.unlock();
|
||||
|
||||
if (old_item)
|
||||
OnUnregistered(name);
|
||||
|
||||
OnRegistered(name, item);
|
||||
return std::shared_lock(m_Mutex);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -133,8 +133,3 @@ std::set<DbType::Ptr> DbType::GetAllTypes()
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
DbTypeRegistry *DbTypeRegistry::GetInstance()
|
||||
{
|
||||
return Singleton<DbTypeRegistry>::GetInstance();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
#include "db_ido/i2-db_ido.hpp"
|
||||
#include "base/object.hpp"
|
||||
#include "base/registry.hpp"
|
||||
#include "base/singleton.hpp"
|
||||
#include <set>
|
||||
|
||||
namespace icinga
|
||||
|
|
@ -57,17 +56,6 @@ private:
|
|||
ObjectMap m_Objects;
|
||||
};
|
||||
|
||||
/**
|
||||
* A registry for DbType objects.
|
||||
*
|
||||
* @ingroup ido
|
||||
*/
|
||||
class DbTypeRegistry : public Registry<DbTypeRegistry, DbType::Ptr>
|
||||
{
|
||||
public:
|
||||
static DbTypeRegistry *GetInstance();
|
||||
};
|
||||
|
||||
/**
|
||||
* Factory function for DbObject-based classes.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
|
||||
|
||||
#include "remote/apiaction.hpp"
|
||||
#include "base/singleton.hpp"
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
INITIALIZE_ONCE_WITH_PRIORITY([]{
|
||||
ApiActionRegistry::GetInstance()->Freeze();
|
||||
}, InitializePriority::FreezeNamespaces);
|
||||
|
||||
ApiAction::ApiAction(std::vector<String> types, Callback action)
|
||||
: m_Types(std::move(types)), m_Callback(std::move(action))
|
||||
{ }
|
||||
|
|
@ -28,8 +31,3 @@ void ApiAction::Register(const String& name, const ApiAction::Ptr& action)
|
|||
{
|
||||
ApiActionRegistry::GetInstance()->Register(name, action);
|
||||
}
|
||||
|
||||
ApiActionRegistry *ApiActionRegistry::GetInstance()
|
||||
{
|
||||
return Singleton<ApiActionRegistry>::GetInstance();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,11 +45,7 @@ private:
|
|||
*
|
||||
* @ingroup remote
|
||||
*/
|
||||
class ApiActionRegistry : public Registry<ApiActionRegistry, ApiAction::Ptr>
|
||||
{
|
||||
public:
|
||||
static ApiActionRegistry *GetInstance();
|
||||
};
|
||||
using ApiActionRegistry = Registry<ApiAction::Ptr>;
|
||||
|
||||
#define REGISTER_APIACTION(name, types, callback) \
|
||||
INITIALIZE_ONCE([]() { \
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
|
||||
|
||||
#include "remote/apifunction.hpp"
|
||||
#include "base/singleton.hpp"
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
INITIALIZE_ONCE_WITH_PRIORITY([]{
|
||||
ApiFunctionRegistry::GetInstance()->Freeze();
|
||||
}, InitializePriority::FreezeNamespaces);
|
||||
|
||||
ApiFunction::ApiFunction(const char* name, Callback function)
|
||||
: m_Name(name), m_Callback(std::move(function))
|
||||
{ }
|
||||
|
|
@ -23,8 +26,3 @@ void ApiFunction::Register(const String& name, const ApiFunction::Ptr& function)
|
|||
{
|
||||
ApiFunctionRegistry::GetInstance()->Register(name, function);
|
||||
}
|
||||
|
||||
ApiFunctionRegistry *ApiFunctionRegistry::GetInstance()
|
||||
{
|
||||
return Singleton<ApiFunctionRegistry>::GetInstance();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,11 +47,7 @@ private:
|
|||
*
|
||||
* @ingroup base
|
||||
*/
|
||||
class ApiFunctionRegistry : public Registry<ApiFunctionRegistry, ApiFunction::Ptr>
|
||||
{
|
||||
public:
|
||||
static ApiFunctionRegistry *GetInstance();
|
||||
};
|
||||
using ApiFunctionRegistry = Registry<ApiFunction::Ptr>;
|
||||
|
||||
#define REGISTER_APIFUNCTION(name, ns, callback) \
|
||||
INITIALIZE_ONCE([]() { \
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
#include "remote/eventqueue.hpp"
|
||||
#include "remote/filterutility.hpp"
|
||||
#include "base/io-engine.hpp"
|
||||
#include "base/singleton.hpp"
|
||||
#include "base/logger.hpp"
|
||||
#include "base/utility.hpp"
|
||||
#include <boost/asio/spawn.hpp>
|
||||
|
|
@ -125,11 +124,6 @@ void EventQueue::Register(const String& name, const EventQueue::Ptr& function)
|
|||
EventQueueRegistry::GetInstance()->Register(name, function);
|
||||
}
|
||||
|
||||
EventQueueRegistry *EventQueueRegistry::GetInstance()
|
||||
{
|
||||
return Singleton<EventQueueRegistry>::GetInstance();
|
||||
}
|
||||
|
||||
std::mutex EventsInbox::m_FiltersMutex;
|
||||
std::map<String, EventsInbox::Filter> EventsInbox::m_Filters ({{"", EventsInbox::Filter{1, Expression::Ptr()}}});
|
||||
|
||||
|
|
|
|||
|
|
@ -59,11 +59,7 @@ private:
|
|||
*
|
||||
* @ingroup base
|
||||
*/
|
||||
class EventQueueRegistry : public Registry<EventQueueRegistry, EventQueue::Ptr>
|
||||
{
|
||||
public:
|
||||
static EventQueueRegistry *GetInstance();
|
||||
};
|
||||
using EventQueueRegistry = Registry<EventQueue::Ptr>;
|
||||
|
||||
enum class EventType : uint_fast8_t
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue