-
Notifications
You must be signed in to change notification settings - Fork 23
RDKEMW-15927: Addressing the occurring race condition while deleting all report profiles #308
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: support/1.8.5
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1159,14 +1159,23 @@ T2ERROR deleteAllProfiles(bool delFromDisk) | |
| int count = 0; | ||
| int profileIndex = 0; | ||
| Profile *tempProfile = NULL; | ||
| static bool deleteInProgress = false; | ||
|
|
||
| pthread_mutex_lock(&plMutex); | ||
| if(deleteInProgress) | ||
| { | ||
| T2Info("deleteAllProfiles already in progress, skipping\n"); | ||
| pthread_mutex_unlock(&plMutex); | ||
| return T2ERROR_SUCCESS; | ||
|
Comment on lines
+1162
to
+1169
|
||
| } | ||
|
|
||
| if(profileList == NULL) | ||
| { | ||
| T2Error("profile list is not initialized yet or profileList is empty, ignoring\n"); | ||
| pthread_mutex_unlock(&plMutex); | ||
| return T2ERROR_FAILURE; | ||
| } | ||
| deleteInProgress = true; | ||
|
|
||
| count = Vector_Size(profileList); | ||
| pthread_mutex_unlock(&plMutex); | ||
|
|
@@ -1216,6 +1225,7 @@ T2ERROR deleteAllProfiles(bool delFromDisk) | |
| Vector_Destroy(profileList, freeProfile); | ||
| profileList = NULL; | ||
| Vector_Create(&profileList); | ||
| deleteInProgress = false; | ||
| pthread_mutex_unlock(&plMutex); | ||
|
|
||
| T2Debug("%s --out\n", __FUNCTION__); | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -381,10 +381,17 @@ rbusError_t eventSubHandler(rbusHandle_t handle, rbusEventSubAction_t action, co | |||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| #if defined(PRIVACYMODES_CONTROL) | ||||||||||||||||||||||||||||
| static pthread_mutex_t privacyWorkerMutex = PTHREAD_MUTEX_INITIALIZER; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||
| * Worker thread to handle privacy mode callbacks off the RBUS handler thread. | ||||||||||||||||||||||||||||
| * Prevents RBUS handler starvation by moving heavy operations (profile deletion, | ||||||||||||||||||||||||||||
| * XConf restart) to a detached thread. | ||||||||||||||||||||||||||||
| * | ||||||||||||||||||||||||||||
| * Serialized via privacyWorkerMutex to prevent concurrent invocations racing on | ||||||||||||||||||||||||||||
| * profile deletion when PrivacyMode is toggled rapidly (e.g. DO_NOT_SHARE -> | ||||||||||||||||||||||||||||
| * SHARE -> DO_NOT_SHARE in quick succession), which causes double-free of | ||||||||||||||||||||||||||||
| * grepSeekProfile in deleteAllProfiles(). | ||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||
| static void* privacyModeCallbackWorker(void *arg) | ||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||
|
|
@@ -395,6 +402,7 @@ static void* privacyModeCallbackWorker(void *arg) | |||||||||||||||||||||||||||
| return NULL; | ||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| T2Debug("%s ++in mode=%s\n", __FUNCTION__, mode); | ||||||||||||||||||||||||||||
| pthread_mutex_lock(&privacyWorkerMutex); | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
| 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; | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new
deleteInProgressearly-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 likeuninitProfileList()(callsdeleteAllProfiles(false)and then destroysplMutex), because a concurrent in-flight delete can continue usingplMutexafter it has been destroyed, leading to undefined behavior/crash.Instead of returning success when
deleteInProgressis true, either (a) wait for the active deletion to complete (e.g.,pthread_cond_waitunderplMutexandpthread_cond_broadcastwhen clearing the flag), or (b) return an error code and update all callers to handle it safely (includinguninitProfileList).