ModernUO/Projects/UOContent/Engines
Kamron Batman dc98cf3cfc
fix(advancedsearch): clear pause and sample exit before signaling the drain
AdvancedSearchThreadWorker.Execute signaled _stopEvent before clearing
_pause and before reading the exit condition. Sleep() unblocks the instant
that signal fires, so the owning thread can start the next cycle while the
worker is still finishing the previous one. Two ways that goes wrong:

- Reuse hang. The next cycle's Wake/Push/Sleep writes _pause = true, then
  the worker's stale `_pause = false` lands on top of it. The inner loop
  never observes pauseRequested, the queue is already empty, and it spins
  on Thread.Yield() forever -- so the owning thread's next Sleep() waits on
  a _stopEvent that is never set again. A single search wakes each worker
  once, so this only surfaces once the shared pool is reused.

- Orphaned Exit. Exit() sets _exit, Wake()s, then Sleep()s, the moment the
  drain's Sleep() returns. Reading _exit after the signal, the worker can
  observe that fresh _exit, return without ever consuming the Wake, and
  leave Exit()'s Sleep() waiting on a signal nobody will send. The IsAlive
  guard does not close this: the thread passes the check and returns
  immediately after.

Both go away by ordering the handshake the way SerializationThreadWorker
already does -- sample the exit condition, clear _pause, then signal. That
worker is the reference for this pattern and is protected by its comment
alone, which is the precedent followed here.

Verified before merge with two throwaway timing tests (25k reuse cycles
and 2k drain-then-Exit cycles): both failed against the previous ordering
and passed with this one. They are not part of the change. Their
reproduction threshold is a property of one machine's scheduler -- at 2k
and 200 cycles the buggy build passed -- so as permanent tests they would
have cost ~560ms and 2000 thread creations per suite run for a guarantee
that may not hold on a CI runner.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-25 15:29:21 -07:00
..
Advanced Search fix(advancedsearch): clear pause and sample exit before signaling the drain 2026-07-25 15:29:21 -07:00
BuffIcons feat: Standardizes South/East selection gumps (#1839) 2025-02-14 00:15:14 -08:00
Bulk Orders perf(saves): eliminate world-save freeze bottlenecks (~9.5x faster freeze) (#2525) 2026-07-16 22:53:28 -07:00
CannedEvil feat: Adds Mobile.Murderer virtual property, consolidates kill-threshold checks (#2355) 2026-03-06 08:36:41 -08:00
Character Creation fix: Fixes bug with non blessed starter spellbooks (#2368) 2026-03-13 00:20:23 -07:00
Chat fix: Bumps deps. Updates copyrights (#2353) 2026-03-05 19:36:54 -08:00
ConPVP feat: Pre-Publish 14 Crafting (supersedes #2181, #2381) (#2476) 2026-06-07 20:27:22 -07:00
Craft feat(throwing): core gargoyle Throwing skill (SA) (#2510) 2026-07-02 21:06:11 -07:00
Doom chore: Use var everywhere (#2294) 2025-12-27 16:47:28 -08:00
Ethics perf(saves): eliminate world-save freeze bottlenecks (~9.5x faster freeze) (#2525) 2026-07-16 22:53:28 -07:00
Events fix: Streamlines event scheduler API. Adds months to weekly recurrence (#2178) 2025-05-07 22:42:44 -07:00
Factions fix: Harden Advanced Search: crash-safety, autosave, correct results & worker fixes (#2543) 2026-07-21 07:51:06 -07:00
FeatureFlags feat: expand cache to nearly all mobiles + dynamic-obstacle pass (#2447) 2026-05-06 00:14:08 -07:00
Harvest chore: Use var everywhere (#2294) 2025-12-27 16:47:28 -08:00
Help feat: Add zero-alloc interpolation handler to ValueStringBuilder, replace all StringBuilder usage (#2387) 2026-03-22 14:23:44 -07:00
Khaldun feat: Converts PuzzleChest to generator, optimizes (#2318) 2026-01-26 21:20:01 -06:00
ML Quests feat: Pre-Publish 14 Crafting (supersedes #2181, #2381) (#2476) 2026-06-07 20:27:22 -07:00
Party fix: Eliminates double lookup with Contains->Remove (#2539) 2026-07-19 09:26:27 -07:00
Pathing fix(pathfinding): stop opening every .swb twice at boot (#2548) 2026-07-25 13:07:20 -07:00
Plants feat: Pre-Publish 14 Crafting (supersedes #2181, #2381) (#2476) 2026-06-07 20:27:22 -07:00
Player Murder System feat: Pre-Publish 14 Crafting (supersedes #2181, #2381) (#2476) 2026-06-07 20:27:22 -07:00
Quests refactor: decompose mobile/corpse hair, delete VirtualHairInfo, fix removal serial (#2462) (#2463) 2026-06-06 14:33:28 -07:00
Spawners refactor(spawners): replace DynamicJson with typed SpawnerDto records (#2505) 2026-06-25 23:24:45 -07:00
Stealables feat(throwing): wire SA loot flavor + Valkyrie's Glaive stealable (#2512) 2026-07-02 22:28:55 -07:00
Treasures of Tokuno fix: Optimizes items to use default weights. (Part 1) (#2240) 2025-07-24 14:44:39 -07:00
UltimaStore fix: Fixes thread guard and cleans up incoming packet reader (#1641) 2023-12-19 17:04:09 -08:00
Veteran Rewards feat: Pre-Publish 14 Crafting (supersedes #2181, #2381) (#2476) 2026-06-07 20:27:22 -07:00
Virtues perf: Migrates Virtue gumps from legacy Gump to DynamicGump/StaticGump. (#2410) 2026-04-25 16:40:07 -07:00