summaryrefslogtreecommitdiff
path: root/Userland/Services
diff options
context:
space:
mode:
authorfaxe1008 <fabianblatz@gmail.com>2021-11-08 11:34:37 +0100
committerAndreas Kling <kling@serenityos.org>2021-11-13 12:55:46 +0100
commita4a89a63cba44951ffdf5b3ece8e65fdf8fa7c94 (patch)
tree6b7a02d3d5645a4cc7ffc9644b5c65cb411720a7 /Userland/Services
parent3ea49259dfe6cf2b58b676b49a890cfc49157d05 (diff)
downloadserenity-a4a89a63cba44951ffdf5b3ece8e65fdf8fa7c94.zip
ConfigServer: Add method and notification for key removal
This addresses the FIXME of detecting ConfigFile key removal.
Diffstat (limited to 'Userland/Services')
-rw-r--r--Userland/Services/ConfigServer/ClientConnection.cpp65
-rw-r--r--Userland/Services/ConfigServer/ClientConnection.h1
-rw-r--r--Userland/Services/ConfigServer/ConfigClient.ipc1
-rw-r--r--Userland/Services/ConfigServer/ConfigServer.ipc1
4 files changed, 50 insertions, 18 deletions
diff --git a/Userland/Services/ConfigServer/ClientConnection.cpp b/Userland/Services/ConfigServer/ClientConnection.cpp
index 11bcd1c0b0..e0ad17c0ee 100644
--- a/Userland/Services/ConfigServer/ClientConnection.cpp
+++ b/Userland/Services/ConfigServer/ClientConnection.cpp
@@ -23,6 +23,14 @@ struct CachedDomain {
static HashMap<String, NonnullOwnPtr<CachedDomain>> s_cache;
static constexpr int s_disk_sync_delay_ms = 5'000;
+static void for_each_monitoring_connection(String const& domain, ClientConnection* excluded_connection, Function<void(ClientConnection&)> callback)
+{
+ for (auto& it : s_connections) {
+ if (it.value->is_monitoring_domain(domain) && (!excluded_connection || it.value != excluded_connection))
+ callback(*it.value);
+ }
+}
+
static Core::ConfigFile& ensure_domain_config(String const& domain)
{
auto it = s_cache.find(domain);
@@ -37,18 +45,24 @@ static Core::ConfigFile& ensure_domain_config(String const& domain)
VERIFY(!result.is_error());
watcher_or_error.value()->on_change = [config, domain](auto&) {
auto new_config = Core::ConfigFile::open(config->filename(), Core::ConfigFile::AllowWriting::Yes);
- // FIXME: Detect removed keys.
+ for (auto& group : config->groups()) {
+ for (auto& key : config->keys(group)) {
+ if (!new_config->has_key(group, key)) {
+ for_each_monitoring_connection(domain, nullptr, [&domain, &group, &key](ClientConnection& connection) {
+ connection.async_notify_removed_key(domain, group, key);
+ });
+ }
+ }
+ }
// FIXME: Detect type of keys.
for (auto& group : new_config->groups()) {
for (auto& key : new_config->keys(group)) {
auto old_value = config->read_entry(group, key);
auto new_value = new_config->read_entry(group, key);
if (old_value != new_value) {
- for (auto& it : s_connections) {
- if (it.value->is_monitoring_domain(domain)) {
- it.value->async_notify_changed_string_value(domain, group, key, new_value);
- }
- }
+ for_each_monitoring_connection(domain, nullptr, [&domain, &group, &key, &new_value](ClientConnection& connection) {
+ connection.async_notify_changed_string_value(domain, group, key, new_value);
+ });
}
}
}
@@ -176,10 +190,9 @@ void ClientConnection::write_string_value(String const& domain, String const& gr
m_dirty_domains.set(domain);
start_or_restart_sync_timer();
- for (auto& it : s_connections) {
- if (it.value != this && it.value->m_monitored_domains.contains(domain))
- it.value->async_notify_changed_string_value(domain, group, key, value);
- }
+ for_each_monitoring_connection(domain, this, [&domain, &group, &key, &value](ClientConnection& connection) {
+ connection.async_notify_changed_string_value(domain, group, key, value);
+ });
}
void ClientConnection::write_i32_value(String const& domain, String const& group, String const& key, i32 value)
@@ -196,10 +209,9 @@ void ClientConnection::write_i32_value(String const& domain, String const& group
m_dirty_domains.set(domain);
start_or_restart_sync_timer();
- for (auto& it : s_connections) {
- if (it.value != this && it.value->m_monitored_domains.contains(domain))
- it.value->async_notify_changed_i32_value(domain, group, key, value);
- }
+ for_each_monitoring_connection(domain, this, [&domain, &group, &key, &value](ClientConnection& connection) {
+ connection.async_notify_changed_i32_value(domain, group, key, value);
+ });
}
void ClientConnection::write_bool_value(String const& domain, String const& group, String const& key, bool value)
@@ -216,10 +228,27 @@ void ClientConnection::write_bool_value(String const& domain, String const& grou
m_dirty_domains.set(domain);
start_or_restart_sync_timer();
- for (auto& it : s_connections) {
- if (it.value != this && it.value->m_monitored_domains.contains(domain))
- it.value->async_notify_changed_bool_value(domain, group, key, value);
- }
+ for_each_monitoring_connection(domain, this, [&domain, &group, &key, &value](ClientConnection& connection) {
+ connection.async_notify_changed_bool_value(domain, group, key, value);
+ });
+}
+
+void ClientConnection::remove_key(String const& domain, String const& group, String const& key)
+{
+ if (!validate_access(domain, group, key))
+ return;
+
+ auto& config = ensure_domain_config(domain);
+ if (!config.has_key(group, key))
+ return;
+
+ config.remove_entry(group, key);
+ m_dirty_domains.set(domain);
+ start_or_restart_sync_timer();
+
+ for_each_monitoring_connection(domain, this, [&domain, &group, &key](ClientConnection& connection) {
+ connection.async_notify_removed_key(domain, group, key);
+ });
}
}
diff --git a/Userland/Services/ConfigServer/ClientConnection.h b/Userland/Services/ConfigServer/ClientConnection.h
index e673bd0b6a..24332b7a02 100644
--- a/Userland/Services/ConfigServer/ClientConnection.h
+++ b/Userland/Services/ConfigServer/ClientConnection.h
@@ -33,6 +33,7 @@ private:
virtual void write_string_value([[maybe_unused]] String const& domain, [[maybe_unused]] String const& group, [[maybe_unused]] String const& key, [[maybe_unused]] String const& value) override;
virtual void write_i32_value([[maybe_unused]] String const& domain, [[maybe_unused]] String const& group, [[maybe_unused]] String const& key, [[maybe_unused]] i32 value) override;
virtual void write_bool_value([[maybe_unused]] String const& domain, [[maybe_unused]] String const& group, [[maybe_unused]] String const& key, [[maybe_unused]] bool value) override;
+ virtual void remove_key([[maybe_unused]] String const& domain, [[maybe_unused]] String const& group, [[maybe_unused]] String const& key) override;
bool validate_access(String const& domain, String const& group, String const& key);
void sync_dirty_domains_to_disk();
diff --git a/Userland/Services/ConfigServer/ConfigClient.ipc b/Userland/Services/ConfigServer/ConfigClient.ipc
index d8436b671d..bd16899025 100644
--- a/Userland/Services/ConfigServer/ConfigClient.ipc
+++ b/Userland/Services/ConfigServer/ConfigClient.ipc
@@ -3,4 +3,5 @@ endpoint ConfigClient
notify_changed_string_value(String domain, String group, String key, String value) =|
notify_changed_i32_value(String domain, String group, String key, i32 value) =|
notify_changed_bool_value(String domain, String group, String key, bool value) =|
+ notify_removed_key(String domain, String group, String key) =|
}
diff --git a/Userland/Services/ConfigServer/ConfigServer.ipc b/Userland/Services/ConfigServer/ConfigServer.ipc
index 055e85241f..a0e65fe213 100644
--- a/Userland/Services/ConfigServer/ConfigServer.ipc
+++ b/Userland/Services/ConfigServer/ConfigServer.ipc
@@ -11,4 +11,5 @@ endpoint ConfigServer
write_string_value(String domain, String group, String key, String value) =|
write_i32_value(String domain, String group, String key, i32 value) =|
write_bool_value(String domain, String group, String key, bool value) =|
+ remove_key(String domain, String group, String key) =|
}