Sfoglia il codice sorgente

Remove the catalog publication lock

The catalog snapshot is already shared ownership, so encrypted consume and
the keepalive no longer hold a lock across the whole transaction. The
keepalive comment now lists the mission seed among standalone roster
triggers.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
stan 4 giorni fa
parent
commit
9437b18438

+ 0 - 1
Sunrise/src/server/bap/encrypted/encrypted_runtime.cpp

@@ -211,7 +211,6 @@ bool consume(Session& session,
              const middleware::bap::OuterFrame& outer,
              std::span<std::byte> response,
              std::size_t& written) noexcept {
-    const state::activity_sdk::CatalogPublicationGuard catalogPublication;
     written = 0;
     session.accountMutationPublished = false;
     if (!session.authenticated) {

+ 2 - 2
Sunrise/src/server/bap/encrypted/push/activity/activity_keepalive_push.cpp

@@ -192,7 +192,6 @@ bool consume_activity_keepalive(Session& session,
                                 std::span<std::byte> response,
                                 std::size_t& written,
                                 bool& touchesScratch) noexcept {
-    const state::activity_sdk::CatalogPublicationGuard catalogPublication;
     written = 0;
     const std::uint64_t now = GetTickCount64();
     const bool keepaliveDue = now >= session.activityKeepaliveDueTick;
@@ -363,7 +362,8 @@ bool consume_activity_keepalive(Session& session,
     // Held until the frame reaches the caller. Encoding alone does not spend the region trigger.
     std::int32_t stagedAdvertisedRegion = -1;
     bool stagedAdvertisedPrivate = false;
-    // Only a changed Host value, retirement or the arrival answer can publish a standalone roster.
+    // Only a changed Host value or mission state, retirement or the arrival answer can publish a
+    // standalone roster.
     if (!keepaliveDue && !regionChanged && !hostTeleportDue) {
         bool appendedRoster = false;
         if (hostStateDue || scriptableDue || retirementDue || arrivalDue || missionSeedDue) {

+ 8 - 21
Sunrise/src/state/activity_sdk/activity_sdk_catalog.cpp

@@ -11,15 +11,6 @@ namespace {
 
 std::atomic<Snapshot> g_snapshot{};
 std::atomic<Status> g_status{Status::notReady};
-SRWLOCK g_publicationLock = SRWLOCK_INIT;
-
-/** Loading/validation happens before this short swap; no game or Host lock is taken here. */
-void publish_snapshot(Snapshot pending, Status status) noexcept {
-    AcquireSRWLockExclusive(&g_publicationLock);
-    g_snapshot.store(std::move(pending), std::memory_order_release);
-    g_status.store(status, std::memory_order_release);
-    ReleaseSRWLockExclusive(&g_publicationLock);
-}
 
 template <typename Value>
 [[nodiscard]] std::span<const Value>
@@ -330,10 +321,12 @@ void initialize(void* module, const ExpectedIdentity& expected) noexcept {
     std::shared_ptr<Catalog> pending;
     Status result = Status::catalogInvalid;
     if (load(module, expected, pending, result)) {
-        publish_snapshot(Snapshot(std::move(pending)), Status::ready);
+        g_snapshot.store(Snapshot(std::move(pending)), std::memory_order_release);
+        g_status.store(Status::ready, std::memory_order_release);
         return;
     }
-    publish_snapshot({}, result);
+    g_snapshot.store({}, std::memory_order_release);
+    g_status.store(result, std::memory_order_release);
 }
 
 /** Keeps the published mapping when a catalog-authorized replacement cannot be authenticated. */
@@ -343,7 +336,8 @@ bool reload(void* module, const ExpectedIdentity& expected) noexcept {
     if (!load(module, expected, pending, result)) {
         return false;
     }
-    publish_snapshot(Snapshot(std::move(pending)), Status::ready);
+    g_snapshot.store(Snapshot(std::move(pending)), std::memory_order_release);
+    g_status.store(Status::ready, std::memory_order_release);
     return true;
 }
 
@@ -368,7 +362,8 @@ bool reload(void* module) noexcept {
 #endif
 
 void shutdown() noexcept {
-    publish_snapshot({}, Status::notReady);
+    g_snapshot.store({}, std::memory_order_release);
+    g_status.store(Status::notReady, std::memory_order_release);
 }
 
 Status status() noexcept {
@@ -957,12 +952,4 @@ const format::Slot* task_linked_objective_slot(const Catalog& catalog,
                : nullptr;
 }
 
-CatalogPublicationGuard::CatalogPublicationGuard() noexcept {
-    AcquireSRWLockShared(&g_publicationLock);
-}
-
-CatalogPublicationGuard::~CatalogPublicationGuard() noexcept {
-    ReleaseSRWLockShared(&g_publicationLock);
-}
-
 } // namespace sunrise::state::activity_sdk

+ 0 - 12
Sunrise/src/state/activity_sdk/runtime.h

@@ -319,18 +319,6 @@ void shutdown() noexcept;
 [[nodiscard]] const char* status_name(MissionSeedStatus value) noexcept;
 /** @return Stable diagnostic text for one authored-scene seed result. */
 [[nodiscard]] const char* status_name(AuthoredSceneSeedStatus value) noexcept;
-/**
- * Keeps catalog publication stable through one transport transaction. Ordinary snapshot reads do
- * not take this lock. Do not reload or nest the guard while one is held.
- */
-class CatalogPublicationGuard final {
-public:
-    CatalogPublicationGuard() noexcept;
-    ~CatalogPublicationGuard() noexcept;
-    CatalogPublicationGuard(const CatalogPublicationGuard&) = delete;
-    CatalogPublicationGuard& operator=(const CatalogPublicationGuard&) = delete;
-};
-
 /** @return Shared ownership of the current validated catalog. */
 [[nodiscard]] Snapshot snapshot() noexcept;
 /** Resolves one route only from the exact loaded SDK registry. */