| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566 |
- #include "../account/settings/settings_delta.h"
- #include "runtime.h"
- #include "storage/internal.h"
- namespace sunrise::state {
- /** Builds a complete checked settings candidate without changing authoritative State. */
- SettingsUpdateDisposition prepare_settings_update(const account::settings::SettingsDelta& delta,
- PendingSettingsUpdate& mutation) noexcept {
- mutation = {};
- const AccountState current = account_snapshot();
- if (!account::valid(current)) {
- return SettingsUpdateDisposition::rejected;
- }
- account::settings::AccountSettings after{};
- bool changed = false;
- if (!account::settings::apply_delta(delta, current.settings, after, changed)) {
- return SettingsUpdateDisposition::rejected;
- }
- if (!changed) {
- return SettingsUpdateDisposition::acceptedNoChange;
- }
- mutation.beforeSettings = current.settings;
- mutation.afterSettings = after;
- mutation.accountSoid = current.primarySoid;
- mutation.prepared = true;
- return SettingsUpdateDisposition::preparedMutation;
- }
- /** Commits a prepared settings image only while its account and settings view remain current. */
- bool commit_settings_update(PendingSettingsUpdate& mutation) noexcept {
- const PendingSettingsUpdate prepared = mutation;
- mutation = {};
- if (!prepared.prepared || prepared.accountSoid == 0
- || prepared.beforeSettings == prepared.afterSettings
- || !account::settings::valid(prepared.beforeSettings)
- || !account::settings::valid(prepared.afterSettings)) {
- return false;
- }
- AcquireSRWLockExclusive(&runtime::storage::g_stateLock);
- AccountState candidate = runtime::storage::g_state.account;
- bool committed = false;
- if (candidate.primarySoid == prepared.accountSoid) {
- if (candidate.settings == prepared.afterSettings) {
- // A second identical transaction may observe the first one's completed after-image.
- committed = account::valid(candidate);
- } else if (candidate.settings == prepared.beforeSettings) {
- candidate.settings = prepared.afterSettings;
- if (account::valid(candidate)) {
- runtime::storage::g_state.account = candidate;
- committed = true;
- }
- }
- }
- ReleaseSRWLockExclusive(&runtime::storage::g_stateLock);
- return committed;
- }
- } // namespace sunrise::state
|