Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 68 additions & 16 deletions source/bulkdata/datamodel.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* If not stated otherwise in this file or this component's LICENSE file the
* following copyright and licenses apply:

Check failure on line 3 in source/bulkdata/datamodel.c

View workflow job for this annotation

GitHub Actions / call-fossid-workflow / Fossid Annotate PR

FossID License Issue Detected

Source code with 'Apache-2.0' license found in local file 'source/bulkdata/datamodel.c' (Match: rdk/components/generic/telemetry/rdk/components/generic/telemetry/1, 404 lines, url: https://code.rdkcentral.com/r/plugins/gitiles/rdk/components/generic/telemetry/+archive/RDKB-RELEASE-TEST-DUNFELL-1.tar.gz, file: source/bulkdata/datamodel.c)
*
* Copyright 2019 RDK Management
*
Expand Down Expand Up @@ -50,17 +50,28 @@
{
(void) data;//To fix compiler warning
cJSON *reportProfiles = NULL;
bool shouldContinue = true;

T2Debug("%s ++in\n", __FUNCTION__);

while(!stopProcessing)
while(shouldContinue)
{
pthread_mutex_lock(&rpMutex);
shouldContinue = !stopProcessing;
if(!shouldContinue)
{
pthread_mutex_unlock(&rpMutex);
break;
}
T2Info("%s: Waiting for event from tr-181 \n", __FUNCTION__);
pthread_cond_wait(&rpCond, &rpMutex);
while(t2_queue_count(rpQueue) == 0 && shouldContinue)
{
pthread_cond_wait(&rpCond, &rpMutex);
shouldContinue = !stopProcessing;
}

T2Debug("%s: Received wake up signal \n", __FUNCTION__);
if(t2_queue_count(rpQueue) > 0)
if(t2_queue_count(rpQueue) > 0 && shouldContinue)
{
reportProfiles = (cJSON *)t2_queue_pop(rpQueue);
if (reportProfiles)
Expand All @@ -80,17 +91,32 @@
{
(void) data;//To fix compiler warning
cJSON *tmpReportProfiles = NULL;
bool shouldContinue = true;

T2Debug("%s ++in\n", __FUNCTION__);

while(!stopProcessing)
while(shouldContinue)
{
pthread_mutex_lock(&tmpRpMutex);
pthread_mutex_lock(&rpMutex);
shouldContinue = !stopProcessing;
pthread_mutex_unlock(&rpMutex);
if(!shouldContinue)
{
pthread_mutex_unlock(&tmpRpMutex);
break;
}
T2Info("%s: Waiting for event from tr-181 \n", __FUNCTION__);
pthread_cond_wait(&tmpRpCond, &tmpRpMutex);
while(t2_queue_count(tmpRpQueue) == 0 && shouldContinue)
{
pthread_cond_wait(&tmpRpCond, &tmpRpMutex);
pthread_mutex_lock(&rpMutex);
shouldContinue = !stopProcessing;
pthread_mutex_unlock(&rpMutex);
}
Comment on lines 100 to +116
Copy link

Copilot AI Feb 15, 2026

Choose a reason for hiding this comment

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

process_tmprp_thread protects tmpRpQueue with tmpRpMutex, but datamodel_processProfile pushes to tmpRpQueue and signals tmpRpCond while holding rpMutex (not tmpRpMutex). Since t2_queue_* is not thread-safe, this inconsistent locking can cause data races and missed wakeups. Consider using tmpRpMutex consistently for tmpRpQueue operations + tmpRpCond signaling (and signal tmpRpCond during shutdown) so the consumer can reliably wake and the queue is properly synchronized.

Copilot uses AI. Check for mistakes.

T2Debug("%s: Received wake up signal \n", __FUNCTION__);
if(t2_queue_count(tmpRpQueue) > 0)
if(t2_queue_count(tmpRpQueue) > 0 && shouldContinue)
{
tmpReportProfiles = (cJSON *)t2_queue_pop(tmpRpQueue);
if (tmpReportProfiles)
Expand All @@ -110,11 +136,31 @@
{
(void) data;//To fix compiler warning
struct __msgpack__ *msgpack;
while(!stopProcessing)
bool shouldContinue = true;

while(shouldContinue)
{
// Check stopProcessing first without holding rpMsgMutex to avoid
// nested mutex acquisition which could lead to deadlock if another
// thread acquires these mutexes in opposite order (e.g., rpMutex then rpMsgMutex)
pthread_mutex_lock(&rpMutex);
shouldContinue = !stopProcessing;
pthread_mutex_unlock(&rpMutex);

if(!shouldContinue)
{
break;
}

pthread_mutex_lock(&rpMsgMutex);
pthread_cond_wait(&msg_Cond, &rpMsgMutex);
if(t2_queue_count(rpMsgPkgQueue) > 0)
while(t2_queue_count(rpMsgPkgQueue) == 0 && shouldContinue)
{
pthread_cond_wait(&msg_Cond, &rpMsgMutex);
pthread_mutex_lock(&rpMutex);
shouldContinue = !stopProcessing;
pthread_mutex_unlock(&rpMutex);
Comment on lines +159 to +161
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

Potential deadlock from nested mutex acquisition. At lines 159-161, rpMutex is acquired while holding rpMsgMutex (locked at line 155). This violates the stated intention in the comment at lines 143-145 to avoid nested mutex acquisition. If another thread acquires rpMutex then tries to acquire rpMsgMutex, a deadlock could occur. Consider checking shouldContinue before entering the while loop at line 156, or restructure to avoid holding rpMsgMutex when acquiring rpMutex.

Copilot uses AI. Check for mistakes.
Copy link
Contributor

Choose a reason for hiding this comment

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

This additional looped call doesn't look right.

}
if(t2_queue_count(rpMsgPkgQueue) > 0 && shouldContinue)
{
msgpack = (struct __msgpack__ *)t2_queue_pop(rpMsgPkgQueue);
if (msgpack)
Expand Down Expand Up @@ -274,18 +320,24 @@

msgpack->msgpack_blob = str;
msgpack->msgpack_blob_size = strSize;
pthread_mutex_lock(&rpMsgMutex);
if (!stopProcessing)
{
t2_queue_push(rpMsgPkgQueue, (void *)msgpack);
pthread_cond_signal(&msg_Cond);
}
else

// Check stopProcessing without holding rpMsgMutex to avoid nested mutex
// acquisition which could lead to deadlock
pthread_mutex_lock(&rpMutex);
bool isProcessing = !stopProcessing;
pthread_mutex_unlock(&rpMutex);

if (!isProcessing)
{
free(msgpack->msgpack_blob);
free(msgpack);
T2Error("Datamodel not initialized, dropping request \n");
return T2ERROR_SUCCESS;
}

pthread_mutex_lock(&rpMsgMutex);
t2_queue_push(rpMsgPkgQueue, (void *)msgpack);
pthread_cond_signal(&msg_Cond);
pthread_mutex_unlock(&rpMsgMutex);
return T2ERROR_SUCCESS;
}
Expand Down
Loading
Loading