Skip to content

Commit 0dced84

Browse files
VPLAY-12337 : Crash issue is observed while switch between different assets
Reason for change: added probable fix for local storage ; instead of using join() use detach() so that thread will not be blocked Test Procedure: updated in the ticket Priority: P1 Risks: Low Signed-off-by: haripriya_molakalapalli <haripriya_molakalapalli@comcast.com>
1 parent 9db43a0 commit 0dced84

File tree

1 file changed

+47
-4
lines changed

1 file changed

+47
-4
lines changed

priv_aamp.cpp

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8151,10 +8151,33 @@ void PrivateInstanceAAMP::Stop( bool isDestructing )
81518151
{
81528152
std::lock_guard<std::mutex> guard(mMutexPlaystart);
81538153
waitforplaystart.notify_all();
8154+
AAMPLOG_WARN("HariPriya Stop: notified PreCache thread, isDestructing=%d", isDestructing);
81548155
}
81558156
if(mPreCachePlaylistThreadId.joinable())
81568157
{
8157-
mPreCachePlaylistThreadId.join();
8158+
auto joinStartTime = NOW_STEADY_TS_MS;
8159+
AAMPLOG_WARN("HariPriya Stop: About to join PreCache thread, isDestructing=%d", isDestructing);
8160+
8161+
// Fix for GC deadlock: During GC finalization (isDestructing=true), the PreCache thread
8162+
// may be blocked in network I/O (curl_easy_perform). Using join() would block the main
8163+
// thread indefinitely, causing freeze/crash. Instead, use detach() to let the thread
8164+
// clean up itself. The thread will exit safely once network I/O completes.
8165+
if (isDestructing)
8166+
{
8167+
AAMPLOG_WARN("HariPriya Stop: Detaching PreCache thread (GC path) to avoid blocking, isDestructing=%d", isDestructing);
8168+
mPreCachePlaylistThreadId.detach();
8169+
}
8170+
else
8171+
{
8172+
// Normal stop path - wait for thread to complete
8173+
mPreCachePlaylistThreadId.join();
8174+
auto joinDuration = NOW_STEADY_TS_MS - joinStartTime;
8175+
AAMPLOG_WARN("HariPriya Stop: PreCache thread joined after %lld ms, isDestructing=%d", joinDuration, isDestructing);
8176+
}
8177+
}
8178+
else
8179+
{
8180+
AAMPLOG_INFO("HariPriya Stop: PreCache thread not joinable, isDestructing=%d", isDestructing);
81588181
}
81598182

81608183
if (mAampCacheHandler)
@@ -10271,14 +10294,17 @@ void PrivateInstanceAAMP::PreCachePlaylistDownloadTask()
1027110294
{
1027210295
// This is the thread function to download all the HLS Playlist in a
1027310296
// differed manner
10297+
AAMPLOG_WARN("PreCachePlaylistDownloadTask: Thread started");
1027410298
int maxWindowForDownload = mPreCacheDnldTimeWindow * 60; // convert to seconds
1027510299
int szPlaylistCount = (int)mPreCacheDnldList.size();
1027610300
if(szPlaylistCount)
1027710301
{
1027810302
// First wait for Tune to complete to start this functionality
1027910303
{
1028010304
std::unique_lock<std::mutex> lock(mMutexPlaystart);
10305+
AAMPLOG_WARN("PreCachePlaylistDownloadTask: Waiting for playstart notification");
1028110306
waitforplaystart.wait(lock);
10307+
AAMPLOG_WARN("PreCachePlaylistDownloadTask: Received playstart notification, proceeding");
1028210308
}
1028310309
// May be Stop is called to release all resources .
1028410310
// Before download , check the state
@@ -10312,7 +10338,25 @@ void PrivateInstanceAAMP::PreCachePlaylistDownloadTask()
1031210338
bool ret = false;
1031310339
// Using StreamLock to avoid StreamAbstractionAAMP deletion when external player commands or stop call received
1031410340
AcquireStreamLock();
10341+
auto getFileStartTime = NOW_STEADY_TS_MS;
10342+
AAMPLOG_WARN("HariPriya PreCachePlaylistDownloadTask: About to call GetFile (network I/O), state=%d", GetState());
10343+
10344+
// DEBUG: Simulate slow network to reproduce GC deadlock issue
10345+
// Set AAMP_SIMULATE_SLOW_PRECACHE_MS env var to inject delay (e.g., export AAMP_SIMULATE_SLOW_PRECACHE_MS=5000)
10346+
const char* delayEnv = getenv("AAMP_SIMULATE_SLOW_PRECACHE_MS");
10347+
if (delayEnv)
10348+
{
10349+
int delayMs = atoi(delayEnv);
10350+
if (delayMs > 0)
10351+
{
10352+
AAMPLOG_WARN("HariPriya PreCachePlaylistDownloadTask: DEBUG - Simulating slow network with %d ms delay", delayMs);
10353+
std::this_thread::sleep_for(std::chrono::milliseconds(delayMs));
10354+
}
10355+
}
10356+
1031510357
ret = GetFile(newelem.url, newelem.type, &playlistStore, playlistEffectiveUrl, &http_code, &downloadTime, NULL, eCURLINSTANCE_PLAYLISTPRECACHE, true );
10358+
auto getFileDuration = NOW_STEADY_TS_MS - getFileStartTime;
10359+
AAMPLOG_WARN("HariPriya PreCachePlaylistDownloadTask: GetFile returned after %lld ms, ret=%d, state=%d", getFileDuration, ret, GetState());
1031610360
ReleaseStreamLock();
1031710361
if(ret != false)
1031810362
{
@@ -10337,11 +10381,12 @@ void PrivateInstanceAAMP::PreCachePlaylistDownloadTask()
1033710381
}
1033810382
}
1033910383
}while (idx < mPreCacheDnldList.size() && state != eSTATE_STOPPING && state != eSTATE_IDLE && state != eSTATE_ERROR);
10384+
AAMPLOG_WARN("HariPriya PreCachePlaylistDownloadTask: Exiting loop, state=%d, idx=%d, size=%zu", state, idx, mPreCacheDnldList.size());
1034010385
mPreCacheDnldList.clear();
1034110386
CurlTerm(eCURLINSTANCE_PLAYLISTPRECACHE);
1034210387
}
1034310388
}
10344-
AAMPLOG_WARN("End of PreCachePlaylistDownloadTask ");
10389+
AAMPLOG_WARN("PreCachePlaylistDownloadTask: Thread exiting, state=%d", GetState());
1034510390
}
1034610391

1034710392
/**
@@ -14448,5 +14493,3 @@ void PrivateInstanceAAMP::SetStreamCaps(AampMediaType type, MediaCodecInfo&& cod
1444814493
if (sink)
1444914494
{
1445014495
sink->SetStreamCaps(type, std::move(codecInfo));
14451-
}
14452-
}

0 commit comments

Comments
 (0)