Skip to content

Commit 8f36871

Browse files
committed
When we shutdown the background thread, delete any tasks queued to run in the background.
Those cannot be dispatched safely since we hold the global lock. P4:10119262 (cherry picked from commit c721d53)
1 parent 2c10cdb commit 8f36871

2 files changed

Lines changed: 62 additions & 0 deletions

File tree

src/steamnetworkingsockets/clientlib/steamnetworkingsockets_lowlevel.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
720772
CTaskList g_taskListRunWithGlobalLock;
721773
CTaskList 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()

src/steamnetworkingsockets/clientlib/steamnetworkingsockets_lowlevel.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -784,6 +784,9 @@ class CTaskList
784784
// Return true if the task list is empty
785785
inline bool empty() const { return m_pFirstTask == nullptr; }
786786

787+
// Delete tasks, without running them.
788+
void DeleteTasks();
789+
787790
private:
788791
// List of queued tasks
789792
CQueuedTask *m_pFirstTask;

0 commit comments

Comments
 (0)