@@ -717,6 +717,58 @@ void CTaskList::RunTasks()
717717 }
718718}
719719
720+ void CTaskList::DeleteTasks ()
721+ {
722+ ShortDurationScopeLock scopeLock ( s_lockTaskQueue );
723+
724+ CQueuedTask *pNextTask = m_pFirstTask;
725+ m_pFirstTask = nullptr ;
726+ m_pLastTask = nullptr ;
727+
728+ while ( pNextTask )
729+ {
730+ CQueuedTask *pTask = pNextTask;
731+ pNextTask = pTask->m_pNextTaskInQueue ;
732+ pTask->m_pNextTaskInQueue = nullptr ;
733+
734+ CTaskTarget *pTarget = pTask->m_pTarget ;
735+ if ( pTarget )
736+ {
737+ CQueuedTask *pPrevForTarget = pTask->m_pPrevTaskForTarget ;
738+ CQueuedTask *pNextForTarget = pTask->m_pNextTaskForTarget ;
739+
740+ if ( pPrevForTarget )
741+ {
742+ Assert ( pTarget->m_pFirstTask != nullptr );
743+ Assert ( pTarget->m_pFirstTask != pTask );
744+ Assert ( pPrevForTarget->m_pTarget == pTarget );
745+ Assert ( pPrevForTarget->m_pNextTaskForTarget == pTask );
746+ pPrevForTarget->m_pNextTaskForTarget = pNextForTarget;
747+ }
748+ else
749+ {
750+ Assert ( pTarget->m_pFirstTask == pTask );
751+ pTarget->m_pFirstTask = pNextForTarget;
752+ }
753+
754+ if ( pNextForTarget )
755+ {
756+ Assert ( pNextForTarget->m_pTarget == pTarget );
757+ Assert ( pNextForTarget->m_pPrevTaskForTarget == pTask );
758+ pNextForTarget->m_pPrevTaskForTarget = pPrevForTarget;
759+ }
760+ }
761+
762+ pTask->m_pTarget = nullptr ;
763+ pTask->m_pPrevTaskForTarget = nullptr ;
764+ pTask->m_pNextTaskForTarget = nullptr ;
765+ pTask->m_eTaskState = CQueuedTask::k_ETaskState_ReadyToDelete;
766+
767+ // Nuke
768+ delete pTask;
769+ }
770+ }
771+
720772CTaskList g_taskListRunWithGlobalLock;
721773CTaskList g_taskListRunInBackground;
722774
@@ -4121,6 +4173,13 @@ void SteamNetworkingSocketsLowLevelDecRef()
41214173 // Shutdown Dual wifi support
41224174 DualWifiShutdown ();
41234175
4176+ // If we have any tasks that were queued to run in the background,
4177+ // we'll have to just abandon them. We don't have enough context
4178+ // here to run them safely because we hold the lock, and some jobs are
4179+ // queued to run in the background precisely because there are
4180+ // potential deadlock issues if they are run while holding the lock.
4181+ g_taskListRunInBackground.DeleteTasks ();
4182+
41244183 // Nuke sockets and COM
41254184 #ifdef _WIN32
41264185 #if !IsXbox()
0 commit comments