summaryrefslogtreecommitdiff
path: root/Userland/Services/ConfigServer
diff options
context:
space:
mode:
Diffstat (limited to 'Userland/Services/ConfigServer')
-rw-r--r--Userland/Services/ConfigServer/ClientConnection.cpp86
-rw-r--r--Userland/Services/ConfigServer/ClientConnection.h3
-rw-r--r--Userland/Services/ConfigServer/ConfigClient.ipc3
-rw-r--r--Userland/Services/ConfigServer/ConfigServer.ipc2
4 files changed, 79 insertions, 15 deletions
diff --git a/Userland/Services/ConfigServer/ClientConnection.cpp b/Userland/Services/ConfigServer/ClientConnection.cpp
index 3551a1af5b..246a95e10f 100644
--- a/Userland/Services/ConfigServer/ClientConnection.cpp
+++ b/Userland/Services/ConfigServer/ClientConnection.cpp
@@ -12,6 +12,25 @@ namespace ConfigServer {
static HashMap<int, RefPtr<ClientConnection>> s_connections;
+struct CachedDomain {
+ String domain;
+ NonnullRefPtr<Core::ConfigFile> config;
+};
+
+static HashMap<String, NonnullOwnPtr<CachedDomain>> s_cache;
+
+static Core::ConfigFile& ensure_domain_config(String const& domain)
+{
+ auto it = s_cache.find(domain);
+ if (it != s_cache.end())
+ return *it->value->config;
+
+ auto config = Core::ConfigFile::open_for_app(domain, Core::ConfigFile::AllowWriting::Yes);
+ auto cache_entry = make<CachedDomain>(domain, config);
+ s_cache.set(domain, move(cache_entry));
+ return *config;
+}
+
ClientConnection::ClientConnection(NonnullRefPtr<Core::LocalSocket> client_socket, int client_id)
: IPC::ClientConnection<ConfigClientEndpoint, ConfigServerEndpoint>(*this, move(client_socket), client_id)
{
@@ -38,6 +57,16 @@ void ClientConnection::pledge_domains(Vector<String> const& domains)
m_pledged_domains.set(domain);
}
+void ClientConnection::monitor_domain(String const& domain)
+{
+ if (m_has_pledged && !m_pledged_domains.contains(domain)) {
+ did_misbehave("Attempt to monitor non-pledged domain");
+ return;
+ }
+
+ m_monitored_domains.set(domain);
+}
+
bool ClientConnection::validate_access(String const& domain, String const& group, String const& key)
{
if (!m_has_pledged)
@@ -53,10 +82,10 @@ Messages::ConfigServer::ReadStringValueResponse ClientConnection::read_string_va
if (!validate_access(domain, group, key))
return nullptr;
- auto config = Core::ConfigFile::open_for_app(domain);
- if (!config->has_key(group, key))
+ auto& config = ensure_domain_config(domain);
+ if (!config.has_key(group, key))
return Optional<String> {};
- return Optional<String> { config->read_entry(group, key) };
+ return Optional<String> { config.read_entry(group, key) };
}
Messages::ConfigServer::ReadI32ValueResponse ClientConnection::read_i32_value(String const& domain, String const& group, String const& key)
@@ -64,10 +93,10 @@ Messages::ConfigServer::ReadI32ValueResponse ClientConnection::read_i32_value(St
if (!validate_access(domain, group, key))
return nullptr;
- auto config = Core::ConfigFile::open_for_app(domain);
- if (!config->has_key(group, key))
+ auto& config = ensure_domain_config(domain);
+ if (!config.has_key(group, key))
return Optional<i32> {};
- return Optional<i32> { config->read_num_entry(group, key) };
+ return Optional<i32> { config.read_num_entry(group, key) };
}
Messages::ConfigServer::ReadBoolValueResponse ClientConnection::read_bool_value(String const& domain, String const& group, String const& key)
@@ -75,10 +104,10 @@ Messages::ConfigServer::ReadBoolValueResponse ClientConnection::read_bool_value(
if (!validate_access(domain, group, key))
return nullptr;
- auto config = Core::ConfigFile::open_for_app(domain);
- if (!config->has_key(group, key))
+ auto& config = ensure_domain_config(domain);
+ if (!config.has_key(group, key))
return Optional<bool> {};
- return Optional<bool> { config->read_bool_entry(group, key) };
+ return Optional<bool> { config.read_bool_entry(group, key) };
}
void ClientConnection::write_string_value(String const& domain, String const& group, String const& key, String const& value)
@@ -86,8 +115,17 @@ void ClientConnection::write_string_value(String const& domain, String const& gr
if (!validate_access(domain, group, key))
return;
- auto config = Core::ConfigFile::open_for_app(domain, Core::ConfigFile::AllowWriting::Yes);
- config->write_entry(group, key, value);
+ auto& config = ensure_domain_config(domain);
+
+ if (config.has_key(group, key) && config.read_entry(group, key) == value)
+ return;
+
+ config.write_entry(group, key, value);
+
+ 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);
+ }
}
void ClientConnection::write_i32_value(String const& domain, String const& group, String const& key, i32 value)
@@ -95,8 +133,17 @@ void ClientConnection::write_i32_value(String const& domain, String const& group
if (!validate_access(domain, group, key))
return;
- auto config = Core::ConfigFile::open_for_app(domain, Core::ConfigFile::AllowWriting::Yes);
- config->write_num_entry(group, key, value);
+ auto& config = ensure_domain_config(domain);
+
+ if (config.has_key(group, key) && config.read_num_entry(group, key) == value)
+ return;
+
+ config.write_num_entry(group, key, value);
+
+ 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);
+ }
}
void ClientConnection::write_bool_value(String const& domain, String const& group, String const& key, bool value)
@@ -104,8 +151,17 @@ void ClientConnection::write_bool_value(String const& domain, String const& grou
if (!validate_access(domain, group, key))
return;
- auto config = Core::ConfigFile::open_for_app(domain, Core::ConfigFile::AllowWriting::Yes);
- config->write_bool_entry(group, key, value);
+ auto& config = ensure_domain_config(domain);
+
+ if (config.has_key(group, key) && config.read_bool_entry(group, key) == value)
+ return;
+
+ config.write_bool_entry(group, key, value);
+
+ 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);
+ }
}
}
diff --git a/Userland/Services/ConfigServer/ClientConnection.h b/Userland/Services/ConfigServer/ClientConnection.h
index cdbc53ab64..55bd3ebb9c 100644
--- a/Userland/Services/ConfigServer/ClientConnection.h
+++ b/Userland/Services/ConfigServer/ClientConnection.h
@@ -24,6 +24,7 @@ private:
explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>, int client_id);
virtual void pledge_domains(Vector<String> const&) override;
+ virtual void monitor_domain(String const&) override;
virtual Messages::ConfigServer::ReadStringValueResponse read_string_value([[maybe_unused]] String const& domain, [[maybe_unused]] String const& group, [[maybe_unused]] String const& key) override;
virtual Messages::ConfigServer::ReadI32ValueResponse read_i32_value([[maybe_unused]] String const& domain, [[maybe_unused]] String const& group, [[maybe_unused]] String const& key) override;
virtual Messages::ConfigServer::ReadBoolValueResponse read_bool_value([[maybe_unused]] String const& domain, [[maybe_unused]] String const& group, [[maybe_unused]] String const& key) override;
@@ -35,6 +36,8 @@ private:
bool m_has_pledged { false };
HashTable<String> m_pledged_domains;
+
+ HashTable<String> m_monitored_domains;
};
}
diff --git a/Userland/Services/ConfigServer/ConfigClient.ipc b/Userland/Services/ConfigServer/ConfigClient.ipc
index bd0318b3ad..d8436b671d 100644
--- a/Userland/Services/ConfigServer/ConfigClient.ipc
+++ b/Userland/Services/ConfigServer/ConfigClient.ipc
@@ -1,3 +1,6 @@
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) =|
}
diff --git a/Userland/Services/ConfigServer/ConfigServer.ipc b/Userland/Services/ConfigServer/ConfigServer.ipc
index 9ce1bbc70a..055e85241f 100644
--- a/Userland/Services/ConfigServer/ConfigServer.ipc
+++ b/Userland/Services/ConfigServer/ConfigServer.ipc
@@ -2,6 +2,8 @@ endpoint ConfigServer
{
pledge_domains(Vector<String> domains) =|
+ monitor_domain(String domain) =|
+
read_string_value(String domain, String group, String key) => (Optional<String> value)
read_i32_value(String domain, String group, String key) => (Optional<i32> value)
read_bool_value(String domain, String group, String key) => (Optional<bool> value)