Skip to content

Fix FragmentfailureRampdown thread safety and divide-by-zero#1371

Merged
pstroffolino merged 4 commits into
dev_sprint_25_2from
feature/VPAAMP-210
May 5, 2026
Merged

Fix FragmentfailureRampdown thread safety and divide-by-zero#1371
pstroffolino merged 4 commits into
dev_sprint_25_2from
feature/VPAAMP-210

Conversation

@benmesander
Copy link
Copy Markdown
Contributor

Add mProfileLock guard when copying mProfiles in
FragmentfailureRampdown. The vector was previously copied without holding the lock, which is undefined behavior if another thread calls clearProfiles()/addProfile() concurrently during a period transition.

Add early return when abrMaxBuffer <= 0 to prevent floating-point divide-by-zero when computing buffer percentage. The AampAbrConfig constructor initializes abrMaxBuffer to 0, so if ReadPlayerConfig has not been called, the division produces Inf.

For the legacy ABR, add a protected getProfileInfoLocked() helper to ABRManager so HybridABRManager can obtain a thread-safe copy of mProfiles without accessing private members directly.

These races are extremely unlikely to manifest, but are addressed here for reasons of code correctness and future proofing.

Applied to both new ABR (abr/abr.cpp) and legacy ABR (support/aampabr/HybridABRManager.cpp, ABRManager.h/cpp). L1 tests added for the abrMaxBuffer guard.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens ABR rampdown logic by fixing a thread-safety issue when copying the profile list during FragmentfailureRampdown, and by preventing a floating-point divide-by-zero when abrMaxBuffer is unset/zero. It also adds unit tests to validate the new guard behavior.

Changes:

  • Add abrMaxBuffer <= 0 guard in FragmentfailureRampdown to avoid divide-by-zero (new and legacy ABR).
  • Make copying of mProfiles thread-safe during rampdown (new ABR via lock; legacy ABR via new locked accessor).
  • Add L1 unit tests covering the abrMaxBuffer == 0 rampdown behavior.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
abr/abr.cpp Adds abrMaxBuffer guard and locks mProfiles while copying in FragmentfailureRampdown.
support/aampabr/HybridABRManager.cpp Adds abrMaxBuffer guard and uses a new locked profile-copy helper in rampdown.
support/aampabr/ABRManager.h Adds getProfileInfoLocked() API for thread-safe access to the profile list.
support/aampabr/ABRManager.cpp Implements getProfileInfoLocked() by copying mProfiles under mProfileLock.
test/utests/tests/AampAbrTests/AbrTests.cpp Adds a unit test asserting rampdown returns 0 when abrMaxBuffer == 0 (new ABR).
test/utests/tests/AampAbrTests/HybridAbrTests.cpp Adds a unit test asserting rampdown returns 0 when abrMaxBuffer == 0 (legacy ABR).

Comment thread support/aampabr/ABRManager.h
Comment thread abr/abr.cpp Outdated
Comment thread abr/abr.cpp Outdated
Add mProfileLock guard when copying mProfiles in
FragmentfailureRampdown. The vector was previously copied without
holding the lock, which is undefined behavior if another thread
calls clearProfiles()/addProfile() concurrently during a period
transition.

Add early return when abrMaxBuffer <= 0 to prevent floating-point
divide-by-zero when computing buffer percentage. The AampAbrConfig
constructor initializes abrMaxBuffer to 0, so if ReadPlayerConfig
has not been called, the division produces Inf.

For the legacy ABR, add a protected getProfileInfoLocked() helper
to ABRManager so HybridABRManager can obtain a thread-safe copy
of mProfiles without accessing private members directly.

These races are extremely unlikely to manifest, but are addressed here
for reasons of code correctness and future proofing.

Applied to both new ABR (abr/abr.cpp) and legacy ABR
(support/aampabr/HybridABRManager.cpp, ABRManager.h/cpp).
L1 tests added for the abrMaxBuffer guard.
@pstroffolino pstroffolino force-pushed the feature/VPAAMP-210 branch from 6ba62c2 to d784a30 Compare May 4, 2026 20:29
@pstroffolino pstroffolino merged commit 449fb7f into dev_sprint_25_2 May 5, 2026
10 checks passed
@pstroffolino pstroffolino deleted the feature/VPAAMP-210 branch May 5, 2026 19:35
Abhi-jith-S pushed a commit that referenced this pull request May 12, 2026
…rofileLock and divide by zero (#1371)

* Fix FragmentfailureRampdown thread safety and divide-by-zero

Reason for Change: harden ABR rampdown logic by fixing a thread-safety issue when copying the profile list during FragmentfailureRampdown, and by preventing a floating-point divide-by-zero when abrMaxBuffer is unset/zero. It also adds unit tests to validate the new guard behavior.

Add mProfileLock guard when copying mProfiles in
FragmentfailureRampdown. The vector was previously copied without
holding the lock, which is undefined behavior if another thread
calls clearProfiles()/addProfile() concurrently during a period
transition.

Add early return when abrMaxBuffer <= 0 to prevent floating-point
divide-by-zero when computing buffer percentage. The AampAbrConfig
constructor initializes abrMaxBuffer to 0, so if ReadPlayerConfig
has not been called, the division produces Inf.

For the legacy ABR, add a protected getProfileInfoLocked() helper
to ABRManager so HybridABRManager can obtain a thread-safe copy
of mProfiles without accessing private members directly.

These races are extremely unlikely to manifest, but are addressed here
for reasons of code correctness and future proofing.

Applied to both new ABR (abr/abr.cpp) and legacy ABR
(support/aampabr/HybridABRManager.cpp, ABRManager.h/cpp).
L1 tests added for the abrMaxBuffer guard.

* Address PR review: remove unused getProfileInfo, fix duplicate log, update FragmentfailureRampdown doc

Risk: Low
Test Guidance: see ticket

---------

Co-authored-by: Philip Stroffolino <philip_stroffolino@cable.comcast.com>
varshnie pushed a commit that referenced this pull request May 18, 2026
…rofileLock and divide by zero (#1371)

* Fix FragmentfailureRampdown thread safety and divide-by-zero

Reason for Change: harden ABR rampdown logic by fixing a thread-safety issue when copying the profile list during FragmentfailureRampdown, and by preventing a floating-point divide-by-zero when abrMaxBuffer is unset/zero. It also adds unit tests to validate the new guard behavior.

Add mProfileLock guard when copying mProfiles in
FragmentfailureRampdown. The vector was previously copied without
holding the lock, which is undefined behavior if another thread
calls clearProfiles()/addProfile() concurrently during a period
transition.

Add early return when abrMaxBuffer <= 0 to prevent floating-point
divide-by-zero when computing buffer percentage. The AampAbrConfig
constructor initializes abrMaxBuffer to 0, so if ReadPlayerConfig
has not been called, the division produces Inf.

For the legacy ABR, add a protected getProfileInfoLocked() helper
to ABRManager so HybridABRManager can obtain a thread-safe copy
of mProfiles without accessing private members directly.

These races are extremely unlikely to manifest, but are addressed here
for reasons of code correctness and future proofing.

Applied to both new ABR (abr/abr.cpp) and legacy ABR
(support/aampabr/HybridABRManager.cpp, ABRManager.h/cpp).
L1 tests added for the abrMaxBuffer guard.

* Address PR review: remove unused getProfileInfo, fix duplicate log, update FragmentfailureRampdown doc

Risk: Low
Test Guidance: see ticket

---------

Co-authored-by: Philip Stroffolino <philip_stroffolino@cable.comcast.com>
varatharajan568 pushed a commit that referenced this pull request May 20, 2026
…rofileLock and divide by zero (#1371)

* Fix FragmentfailureRampdown thread safety and divide-by-zero

Reason for Change: harden ABR rampdown logic by fixing a thread-safety issue when copying the profile list during FragmentfailureRampdown, and by preventing a floating-point divide-by-zero when abrMaxBuffer is unset/zero. It also adds unit tests to validate the new guard behavior.

Add mProfileLock guard when copying mProfiles in
FragmentfailureRampdown. The vector was previously copied without
holding the lock, which is undefined behavior if another thread
calls clearProfiles()/addProfile() concurrently during a period
transition.

Add early return when abrMaxBuffer <= 0 to prevent floating-point
divide-by-zero when computing buffer percentage. The AampAbrConfig
constructor initializes abrMaxBuffer to 0, so if ReadPlayerConfig
has not been called, the division produces Inf.

For the legacy ABR, add a protected getProfileInfoLocked() helper
to ABRManager so HybridABRManager can obtain a thread-safe copy
of mProfiles without accessing private members directly.

These races are extremely unlikely to manifest, but are addressed here
for reasons of code correctness and future proofing.

Applied to both new ABR (abr/abr.cpp) and legacy ABR
(support/aampabr/HybridABRManager.cpp, ABRManager.h/cpp).
L1 tests added for the abrMaxBuffer guard.

* Address PR review: remove unused getProfileInfo, fix duplicate log, update FragmentfailureRampdown doc

Risk: Low
Test Guidance: see ticket

---------

Co-authored-by: Philip Stroffolino <philip_stroffolino@cable.comcast.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants