7.4 KiB
DEADLOCK FIX STATUS - PHASE 3 ANALYSIS COMPLETE ✅
COMPREHENSIVE AUDIT FINDINGS
Total ObjectAccessor Calls from Worker Threads: 31 calls
Systems Affected:
- ✅ TargetScanner (3 calls) - FIXED
- ⚠️ ClassAI (5 calls) - PARTIALLY FIXED (UnholySpecialization done, EvokerAI done)
- ❌ QuestManager (11 calls) - AUTOMATED FIX INCOMPLETE
- ❌ GatheringManager (5 calls) - AUTOMATED FIX INCOMPLETE
- ❌ Strategy Systems (10 calls) - AUTOMATED FIX INCOMPLETE
PHASE 1: TargetScanner (COMPLETE ✅)
ROOT CAUSE ELIMINATED: TargetScanner methods no longer access Map from worker threads
Files Fixed:
-
TargetScanner.h- Changed return types to ObjectGuid- FindNearestHostile() → ObjectGuid
- FindBestTarget() → ObjectGuid
- FindAllHostiles() → std::vector
-
TargetScanner.cpp- Eliminated ObjectAccessor::GetUnit() calls- FindAllHostiles: Returns GUIDs from snapshot data (line 249-337)
- FindBestTarget: Priority calculation using snapshot data (line 183-264)
- FindNearestHostile: Distance calculation using snapshot data (line 128-181)
-
BotAI.cpp- Updated caller to resolve GUIDs on main thread (line 948-958)- Gets ObjectGuid from FindBestTarget()
- Resolves GUID → Unit* on main thread (safe)
- Validates before engaging
Impact: MASSIVE - TargetScanner is called hundreds of times per second across thousands of bots
PHASE 2: ClassAI Critical Methods (COMPLETE ✅)
Files Fixed:
-
DeathKnights/UnholySpecialization.h/cpp- UpdateGhoulManagement: Now accepts target parameter (line 1555)
- CommandGhoulIfNeeded: Now accepts target parameter (line 1603)
- HandleEmergencySurvival: Now accepts target parameter (fixed)
- UpdateCombatPhase: Now accepts target parameter (fixed)
- Eliminated ObjectAccessor call from worker thread
-
Evokers/EvokerAI.h/cpp- UpdateEssenceManagement: Now accepts target parameter (line 656)
- Eliminated ObjectAccessor calls from worker thread
Impact: SIGNIFICANT - These methods run on worker threads for every bot update
PHASE 3: Quest/Gathering/Strategy Systems (ANALYSIS COMPLETE)
CRITICAL DISCOVERY: DEEPER REFACTORING NEEDED
Problem: Automated script replaced ObjectAccessor calls but code logic still depends on pointers throughout method bodies
Example:
// AUTOMATED FIX (BROKEN):
ObjectGuid creatureGuid = guid; // Replaced ObjectAccessor call
if (!creature || creature->isDead()) // ERROR: creature undefined!
continue;
Files Affected:
- QuestCompletion.cpp (20 compilation errors)
- QuestPickup.cpp (automated fix incomplete)
- QuestTurnIn.cpp (automated fix incomplete)
- GatheringManager.cpp (automated fix incomplete)
- LootStrategy.cpp (automated fix incomplete)
- QuestStrategy.cpp (1 compilation error)
- CombatMovementStrategy.cpp (automated fix incomplete)
TWO SOLUTIONS AVAILABLE
Option A: Complete Snapshot Integration (4-6 hours)
- Enhance DoubleBufferedSpatialGrid with GameObject snapshots
- Add quest/gathering fields to CreatureSnapshot
- Manually refactor ALL 31 methods to use snapshots
- Pros: Complete thread-safe solution, future-proof
- Cons: Time-consuming, complex logic changes
Option B: Main Thread Execution (30 minutes) ⭐ RECOMMENDED
- Move UpdateManagers() from BotAI::UpdateAI() to World::Update()
- Quest/Gathering/Strategy execute on MAIN THREAD
- ObjectAccessor calls become SAFE (main thread has Map access)
- Pros: Quick, eliminates deadlock immediately, proven pattern
- Cons: Not "pure" thread-safe, managers run on main thread
RECOMMENDATION: OPTION B
Why Option B is Better RIGHT NOW:
- Immediate Results: Can test with 5000+ bots TODAY
- Proven TrinityCore Pattern: Manager updates on main thread is standard
- Preserves Combat Performance: ClassAI rotations still run on worker threads
- Low Risk: Minimal code changes, no complex refactoring
- Iterative Improvement: Can still do Option A later as enhancement
Implementation Plan for Option B:
Step 1: Revert automated Quest/Gathering/Strategy changes
git checkout -- src/modules/Playerbot/Quest/
git checkout -- src/modules/Playerbot/Professions/GatheringManager.cpp
git checkout -- src/modules/Playerbot/AI/Strategy/
Step 2: Move UpdateManagers() to main thread
File: BotAI.cpp line 502
// REMOVE UpdateManagers(diff) from BotAI::UpdateAI()
File: World.cpp after line 2356 (after bot actions, before Map updates)
// Process bot manager updates on MAIN THREAD
{
TC_METRIC_TIMER("world_update_time", TC_METRIC_TAG("type", "Bot Manager Updates"));
if (sPlayerBotMgr)
sPlayerBotMgr->UpdateAllBotManagers(diff);
}
File: PlayerBotMgr.h
void UpdateAllBotManagers(uint32 diff);
File: PlayerBotMgr.cpp
void PlayerBotMgr::UpdateAllBotManagers(uint32 diff)
{
for (auto& [guid, bot] : _bots)
{
if (BotAI* ai = bot->GetBotAI())
ai->UpdateManagers(diff);
}
}
Step 3: Build and test
WHAT RUNS WHERE (AFTER OPTION B)
Worker Threads (Thread Pool):
- ✅ BotAI::UpdateAI() - Main AI logic
- ✅ ClassAI::UpdateRotation() - Combat rotations (TargetScanner returns GUIDs safely)
- ✅ Movement updates
- ✅ Behavior priority processing
- ✅ Strategy trigger evaluation
Main Thread (World::Update):
- ✅ Bot action processing (BotActionProcessor)
- ✅ QuestManager::Update() - Safe ObjectAccessor usage
- ✅ GatheringManager::Update() - Safe ObjectAccessor usage
- ✅ TradeManager::Update() - Safe ObjectAccessor usage
- ✅ AuctionManager::Update() - Safe ObjectAccessor usage
- ✅ Strategy execution - Safe ObjectAccessor usage
- ✅ Map::Update()
TESTING CHECKLIST (AFTER OPTION B)
- Revert automated Quest/Gathering/Strategy changes
- Implement PlayerBotMgr::UpdateAllBotManagers()
- Move UpdateManagers() call to World::Update()
- Build succeeds
- Spawn 100 bots - verify futures complete
- Spawn 1000 bots - verify futures complete
- Spawn 5000 bots - CRITICAL TEST: futures 3-14 MUST complete
- Monitor for 60-second hangs - MUST BE ZERO
- Verify quest operations work
- Verify gathering operations work
- Verify combat rotations work
- Check server logs for deadlock warnings
COMPILATION STATUS
Current: ❌ 20+ errors in Quest/Strategy files (automated fix incomplete)
Files Compiling:
- ✅ TargetScanner.cpp
- ✅ TargetScanner.h
- ✅ BotAI.cpp
- ✅ UnholySpecialization.cpp
- ✅ UnholySpecialization.h
- ✅ EvokerAI.cpp
- ✅ EvokerAI.h
Files Failing:
- ❌ QuestCompletion.cpp (20 errors - uses undefined 'creature' pointer)
- ❌ QuestStrategy.cpp (1 error - uses undefined 'gameObject' pointer)
SUMMARY
ANALYSIS COMPLETE: All 31 ObjectAccessor calls identified and documented
OPTION B RECOMMENDED: Move manager updates to main thread (30 min implementation)
EXPECTED OUTCOME: 100% deadlock elimination, futures 3-14 complete with 5000+ bots
NEXT STEP: Implement Option B OR choose Option A for complete snapshot integration
DOCUMENTATION FILES
COMPLETE_DEADLOCK_AUDIT.md- Full audit of all 31 ObjectAccessor callsDEADLOCK_FIX_PHASE3_STATUS.md- Detailed status and recommendationsfix_all_objectaccessor_deadlocks.py- Automated fix script (incomplete for Quest/Gathering/Strategy)