Skip to content

RDKEMW-15927: Addressing the occurring race condition while deleting all report profiles#308

Open
yogeswaransky wants to merge 1 commit intosupport/1.8.5from
topic/deletion_racecondition
Open

RDKEMW-15927: Addressing the occurring race condition while deleting all report profiles#308
yogeswaransky wants to merge 1 commit intosupport/1.8.5from
topic/deletion_racecondition

Conversation

@yogeswaransky
Copy link
Copy Markdown
Contributor

No description provided.

…ort profiles

Signed-off-by: Yogeswaran K <yogeswaransky@gmail.com>
@yogeswaransky yogeswaransky requested a review from a team as a code owner April 2, 2026 11:11
Copilot AI review requested due to automatic review settings April 2, 2026 11:11
@yogeswaransky yogeswaransky changed the title RDKEMW-15927: Adrressing the race condition in while deleting all report profiles RDKEMW-15927: Addressing the occurring race condition while deleting all report profiles Apr 2, 2026
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

Addresses a reported race condition when deleting all report profiles (notably during rapid PrivacyMode toggling), aiming to prevent concurrent deletion paths from corrupting profile state.

Changes:

  • Serialize PrivacyMode callback handling in rbusInterface.c using a process-wide mutex.
  • Add a deleteInProgress guard in deleteAllProfiles() to prevent concurrent re-entry.

Reviewed changes

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

File Description
source/ccspinterface/rbusInterface.c Adds a global mutex to serialize privacy callback worker execution to avoid concurrent profile-deletion actions.
source/bulkdata/profile.c Adds an in-progress flag to avoid re-entrant deleteAllProfiles() executions.

Comment on lines +1165 to +1169
if(deleteInProgress)
{
T2Info("deleteAllProfiles already in progress, skipping\n");
pthread_mutex_unlock(&plMutex);
return T2ERROR_SUCCESS;
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

The new deleteInProgress early-return changes the function’s semantics from “delete completes before return” to “may return while another thread is still deleting”. This is dangerous for callers like uninitProfileList() (calls deleteAllProfiles(false) and then destroys plMutex), because a concurrent in-flight delete can continue using plMutex after it has been destroyed, leading to undefined behavior/crash.

Instead of returning success when deleteInProgress is true, either (a) wait for the active deletion to complete (e.g., pthread_cond_wait under plMutex and pthread_cond_broadcast when clearing the flag), or (b) return an error code and update all callers to handle it safely (including uninitProfileList).

Suggested change
if(deleteInProgress)
{
T2Info("deleteAllProfiles already in progress, skipping\n");
pthread_mutex_unlock(&plMutex);
return T2ERROR_SUCCESS;
if (deleteInProgress)
{
T2Info("deleteAllProfiles already in progress, waiting for completion\n");
/* Wait until the ongoing delete operation completes.
* This restores the guarantee that deleteAllProfiles does not
* return while another thread is still deleting and using plMutex.
*/
while (deleteInProgress)
{
pthread_mutex_unlock(&plMutex);
/* Sleep briefly to avoid busy-waiting while allowing the
* active deleter to make progress.
*/
usleep(1000);
pthread_mutex_lock(&plMutex);
}

Copilot uses AI. Check for mistakes.
Comment on lines +1162 to +1169
static bool deleteInProgress = false;

pthread_mutex_lock(&plMutex);
if(deleteInProgress)
{
T2Info("deleteAllProfiles already in progress, skipping\n");
pthread_mutex_unlock(&plMutex);
return T2ERROR_SUCCESS;
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

deleteInProgress is set/reset without any test coverage to verify the new behavior (re-entrant calls, waiting/skipping behavior, and interaction with teardown paths like uninitProfileList). Since this change is specifically addressing a race condition, please add unit tests that exercise concurrent/overlapping deleteAllProfiles calls (e.g., block the first call mid-way via mocks and verify the second call’s behavior).

Copilot generated this review using guidance from repository custom instructions.
return NULL;
}
T2Debug("%s ++in mode=%s\n", __FUNCTION__, mode);
pthread_mutex_lock(&privacyWorkerMutex);
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

Serializing the entire worker with a global mutex can cause unbounded accumulation of detached threads if PrivacyMode is toggled rapidly: each event still spawns a new thread, and additional threads will block on privacyWorkerMutex while holding full thread stacks. Consider coalescing events (single long-lived worker thread + queue), or using pthread_mutex_trylock/an atomic “worker running” flag to drop or merge redundant invocations rather than creating another thread that will just wait.

Suggested change
pthread_mutex_lock(&privacyWorkerMutex);
/* Use trylock to avoid blocking multiple detached threads on the
* global mutex. If another worker is already running, drop this
* redundant invocation to prevent unbounded accumulation of waiting
* threads (each holding a full stack).
*/
if(pthread_mutex_trylock(&privacyWorkerMutex) != 0)
{
T2Debug("%s: privacyWorkerMutex busy, skipping redundant privacyModeCallbackWorker for mode=%s\n",
__FUNCTION__, mode);
free(mode);
return NULL;
}

Copilot uses AI. Check for mistakes.
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.

2 participants