summaryrefslogtreecommitdiff
path: root/Userland/Services/ConfigServer/ClientConnection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Userland/Services/ConfigServer/ClientConnection.cpp')
-rw-r--r--Userland/Services/ConfigServer/ClientConnection.cpp86
1 files changed, 71 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);
+ }
}
}