瀏覽代碼

Convert client/content

Kenny Mecham 2 周之前
父節點
當前提交
b0d6587071

+ 6 - 5
Sunrise/src/client/content/investment/investment_refresh.cpp

@@ -1,17 +1,20 @@
 #include <Windows.h>
 #include <Windows.h>
 
 
+#include <mutex>
+
 #include "../../../core/ui/busy/busy.h"
 #include "../../../core/ui/busy/busy.h"
 #include "../../../middleware/content/packages/reader/reader.h"
 #include "../../../middleware/content/packages/reader/reader.h"
 #include "../../../state/build_data/runtime.h"
 #include "../../../state/build_data/runtime.h"
 #include "../../../state/runtime/runtime.h"
 #include "../../../state/runtime/runtime.h"
 #include "../items/packages/build.h"
 #include "../items/packages/build.h"
+#include "core/threading/srw_lock.h"
 #include "internal.h"
 #include "internal.h"
 #include "runtime.h"
 #include "runtime.h"
 
 
 namespace sunrise::client::content::investment {
 namespace sunrise::client::content::investment {
 namespace {
 namespace {
 
 
-SRWLOCK g_refreshLock{SRWLOCK_INIT};
+core::threading::SrwLock g_refreshLock{};
 
 
 /**
 /**
  * @return True when every persistent mapping domain is fully published.
  * @return True when every persistent mapping domain is fully published.
@@ -47,19 +50,18 @@ bool refresh() noexcept {
     if (ready()) {
     if (ready()) {
         // The same lock as the extraction path. A cache write holds its own lock across file
         // The same lock as the extraction path. A cache write holds its own lock across file
         // calls, so a held thread stopped inside one would deadlock the freeze below.
         // calls, so a held thread stopped inside one would deadlock the freeze below.
-        AcquireSRWLockExclusive(&g_refreshLock);
+        const std::lock_guard lock(g_refreshLock);
         const bool persisted = state::ensure_profile_item_identities()
         const bool persisted = state::ensure_profile_item_identities()
                                && state::ensure_character_subclasses()
                                && state::ensure_character_subclasses()
                                && state::build_data::persist();
                                && state::build_data::persist();
         // Nothing reads a package again until the next boot, so the open files and the held
         // Nothing reads a package again until the next boot, so the open files and the held
         // tables go back now rather than at process exit.
         // tables go back now rather than at process exit.
         middleware::content::packages::reader::release_caches();
         middleware::content::packages::reader::release_caches();
-        ReleaseSRWLockExclusive(&g_refreshLock);
         core::ui::busy::end(core::ui::busy::Task::contentExtraction);
         core::ui::busy::end(core::ui::busy::Task::contentExtraction);
         return persisted;
         return persisted;
     }
     }
 
 
-    AcquireSRWLockExclusive(&g_refreshLock);
+    const std::lock_guard lock(g_refreshLock);
     // The package pass creates parallel readers. Suspending the client while those threads start
     // The package pass creates parallel readers. Suspending the client while those threads start
     // can block their DLL thread-attach work behind a suspended owner, so the visible preflight
     // can block their DLL thread-attach work behind a suspended owner, so the visible preflight
     // runs one frame early and extraction proceeds with the process live.
     // runs one frame early and extraction proceeds with the process live.
@@ -73,7 +75,6 @@ bool refresh() noexcept {
     if (complete) {
     if (complete) {
         core::ui::busy::end(core::ui::busy::Task::contentExtraction);
         core::ui::busy::end(core::ui::busy::Task::contentExtraction);
     }
     }
-    ReleaseSRWLockExclusive(&g_refreshLock);
     return complete;
     return complete;
 }
 }
 
 

+ 50 - 47
Sunrise/src/client/content/investment/worker/investment_refresh_worker.cpp

@@ -6,6 +6,7 @@
 #include "../internal.h"
 #include "../internal.h"
 #include "../runtime.h"
 #include "../runtime.h"
 #include "../worker.h"
 #include "../worker.h"
+#include "core/threading/data_mutex.h"
 
 
 namespace sunrise::client::content::investment::worker {
 namespace sunrise::client::content::investment::worker {
 namespace {
 namespace {
@@ -17,73 +18,75 @@ namespace {
  */
  */
 constexpr std::uint64_t kRefreshIntervalMilliseconds = 0;
 constexpr std::uint64_t kRefreshIntervalMilliseconds = 0;
 
 
-SRWLOCK g_lifecycleLock{SRWLOCK_INIT};
-bool g_accepting{};
-bool g_complete{};
-bool g_overlayPending{};
-std::uint64_t g_nextEligible{};
+struct Lifecycle {
+    bool accepting{};
+    bool complete{};
+    bool overlayPending{};
+    std::uint64_t nextEligible{};
+};
+
+core::threading::DataMutex<Lifecycle> g_lifecycle{};
 
 
 } // namespace
 } // namespace
 
 
 /** Allows cooperative investment refresh slices on the caller-owned game thread. */
 /** Allows cooperative investment refresh slices on the caller-owned game thread. */
 void activate() noexcept {
 void activate() noexcept {
-    AcquireSRWLockExclusive(&g_lifecycleLock);
-    g_accepting = true;
-    g_complete = false;
-    g_overlayPending = false;
-    g_nextEligible = 0;
-    sunrise::core::ui::busy::end(sunrise::core::ui::busy::Task::contentExtraction);
-    ReleaseSRWLockExclusive(&g_lifecycleLock);
+    g_lifecycle.lock([](Lifecycle& lifecycle) {
+        lifecycle.accepting = true;
+        lifecycle.complete = false;
+        lifecycle.overlayPending = false;
+        lifecycle.nextEligible = 0;
+        sunrise::core::ui::busy::end(sunrise::core::ui::busy::Task::contentExtraction);
+    });
 }
 }
 
 
 /** Runs one due bounded refresh slice on the caller-owned game thread. */
 /** Runs one due bounded refresh slice on the caller-owned game thread. */
 void service(std::uint64_t nowMilliseconds) noexcept {
 void service(std::uint64_t nowMilliseconds) noexcept {
-    AcquireSRWLockExclusive(&g_lifecycleLock);
-    if (!g_accepting || g_complete || !sunrise::client::targets::game::content::is_resolved()
-        || nowMilliseconds < g_nextEligible) {
-        ReleaseSRWLockExclusive(&g_lifecycleLock);
-        return;
-    }
-    g_nextEligible = nowMilliseconds + kRefreshIntervalMilliseconds;
-
-    if (sunrise::client::content::investment::requires_package_sweep()) {
-        g_overlayPending = true;
-        if (sunrise::core::ui::busy::raise_early(
-                sunrise::core::ui::busy::Task::contentExtraction)) {
-            ReleaseSRWLockExclusive(&g_lifecycleLock);
+    g_lifecycle.lock([nowMilliseconds](Lifecycle& lifecycle) {
+        if (!lifecycle.accepting || lifecycle.complete
+            || !sunrise::client::targets::game::content::is_resolved()
+            || nowMilliseconds < lifecycle.nextEligible) {
             return;
             return;
         }
         }
-    } else if (g_overlayPending) {
-        // A stale preflight must not leave a task raised after another path publishes the rows.
-        sunrise::core::ui::busy::end(sunrise::core::ui::busy::Task::contentExtraction);
-        g_overlayPending = false;
-    }
+        lifecycle.nextEligible = nowMilliseconds + kRefreshIntervalMilliseconds;
 
 
-    g_complete = sunrise::client::content::investment::refresh();
-    sunrise::client::content::diagnostics::report_readiness();
-    g_overlayPending = false;
-    ReleaseSRWLockExclusive(&g_lifecycleLock);
+        if (sunrise::client::content::investment::requires_package_sweep()) {
+            lifecycle.overlayPending = true;
+            if (sunrise::core::ui::busy::raise_early(
+                    sunrise::core::ui::busy::Task::contentExtraction)) {
+                return;
+            }
+        } else if (lifecycle.overlayPending) {
+            // A stale preflight must not leave a task raised after another path publishes the rows.
+            sunrise::core::ui::busy::end(sunrise::core::ui::busy::Task::contentExtraction);
+            lifecycle.overlayPending = false;
+        }
+
+        lifecycle.complete = sunrise::client::content::investment::refresh();
+        sunrise::client::content::diagnostics::report_readiness();
+        lifecycle.overlayPending = false;
+    });
 }
 }
 
 
 /** Stops taking refresh slices and clears the pending overlay. */
 /** Stops taking refresh slices and clears the pending overlay. */
 void reset() noexcept {
 void reset() noexcept {
-    AcquireSRWLockExclusive(&g_lifecycleLock);
-    g_accepting = false;
-    g_complete = false;
-    g_overlayPending = false;
-    g_nextEligible = 0;
-    sunrise::core::ui::busy::end(sunrise::core::ui::busy::Task::contentExtraction);
-    ReleaseSRWLockExclusive(&g_lifecycleLock);
+    g_lifecycle.lock([](Lifecycle& lifecycle) {
+        lifecycle.accepting = false;
+        lifecycle.complete = false;
+        lifecycle.overlayPending = false;
+        lifecycle.nextEligible = 0;
+        sunrise::core::ui::busy::end(sunrise::core::ui::busy::Task::contentExtraction);
+    });
 }
 }
 
 
 /** Makes the next due pump take another refresh slice even though a prior one completed. */
 /** Makes the next due pump take another refresh slice even though a prior one completed. */
 void request_slice() noexcept {
 void request_slice() noexcept {
-    AcquireSRWLockExclusive(&g_lifecycleLock);
-    if (g_accepting) {
-        g_complete = false;
-        g_nextEligible = 0;
-    }
-    ReleaseSRWLockExclusive(&g_lifecycleLock);
+    g_lifecycle.lock([](Lifecycle& lifecycle) {
+        if (lifecycle.accepting) {
+            lifecycle.complete = false;
+            lifecycle.nextEligible = 0;
+        }
+    });
 }
 }
 
 
 } // namespace sunrise::client::content::investment::worker
 } // namespace sunrise::client::content::investment::worker