Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
9dc285d
Fix Coverity identified issues - dobby
dkumar798 Jan 13, 2026
bb782fd
RDKEMW-12282: Fix Coverity identified issues - dobby
dkumar798 Jan 21, 2026
8ba7846
Update DobbyManager.cpp
dkumar798 Jan 21, 2026
9388819
Update DobbyManager.cpp
dkumar798 Jan 22, 2026
f75dfe6
Update DobbyManager.cpp
dkumar798 Jan 22, 2026
9756bc7
Update DobbyManager.cpp
dkumar798 Jan 22, 2026
1a532ab
RDKEMW-12282: Fix Coverity identified issues - dobby
dkumar798 Jan 22, 2026
161d7b0
RDKEMW-12282: Fix Coverity identified issues - dobby
dkumar798 Jan 22, 2026
7832785
Update RefCountFile.cpp
dkumar798 Jan 22, 2026
60aac7c
RDKEMW-12282: Fix Coverity identified issues - dobby
dkumar798 Jan 22, 2026
06a0de3
Update ThreadedDispatcher.cpp
dkumar798 Jan 23, 2026
f6adb02
Update Notifier.h
dkumar798 Jan 23, 2026
b39b464
Update DobbyManager.cpp
dkumar798 Jan 23, 2026
c1c6dbd
RDKEMW-12282: Fix Coverity identified issues - dobby
dkumar798 Jan 23, 2026
2730884
Update ThreadedDispatcher.cpp
dkumar798 Jan 23, 2026
e0d2038
RDKEMW-12282: Fix Coverity identified issues - dobby
dkumar798 Jan 23, 2026
ad315d1
Update DobbyBundleConfig.cpp
dkumar798 Jan 23, 2026
a495ad9
Update DobbyLogger.cpp
dkumar798 Jan 23, 2026
f5138f9
Update DobbyTemplate.cpp
dkumar798 Jan 23, 2026
b7d7f2f
Update ThreadedDispatcher.cpp
dkumar798 Feb 4, 2026
03f92fe
Update ServiceMonitor.cpp
dkumar798 Feb 4, 2026
9756d4a
Update ThreadedDispatcher.cpp
dkumar798 Feb 4, 2026
dc87f41
Update DobbyBundleConfig.cpp
dkumar798 Feb 4, 2026
2077a4e
Update DobbyProxy.cpp
dkumar798 Feb 4, 2026
572c7b3
Update DobbyIpcBus.cpp
dkumar798 Feb 5, 2026
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
1 change: 0 additions & 1 deletion AppInfrastructure/Common/include/ConditionVariable.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,6 @@ class ConditionVariable
else
{
__ConditionVariableThrowOnError(err);
return std::cv_status::timeout;
}
}

Expand Down
10 changes: 9 additions & 1 deletion AppInfrastructure/Common/include/IDGenerator.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

#include <bitset>
#include <mutex>
#include <random>

#include <math.h>
#include <stdlib.h>
Expand Down Expand Up @@ -85,10 +86,17 @@ class IDGenerator
(N == 19) ? 0x4032F :
(N == 20) ? 0x80534 : 0;

private:
static unsigned getRandomSeed()
{
std::random_device rd;
return rd();
}

public:
IDGenerator(unsigned offset = 0)
: mOffset(offset)
, mLfsr(1 + (rand() % (mSize- 2)))
, mLfsr(1 + (getRandomSeed() % (mSize - 2)))
{ }

public:
Expand Down
42 changes: 22 additions & 20 deletions AppInfrastructure/Common/source/ThreadedDispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ void ThreadedDispatcher::post(std::function<void ()> work)
if(running)
{
q.push_back(work);
lock.unlock();
cv.notify_one();
}
else
Expand Down Expand Up @@ -74,7 +73,6 @@ void syncCallback(std::mutex* lock, std::condition_variable* cond, bool* fired)
std::unique_lock<std::mutex> locker(*lock);
*fired = true;
cond->notify_all();
locker.unlock();
}
} // namespace
/**
Expand Down Expand Up @@ -117,7 +115,6 @@ void ThreadedDispatcher::sync()
}
// Add the work object to the queue which takes the lock and sets 'fired' to true
q.push_back(std::bind(syncCallback, &lock, &cond, &fired));
qlocker.unlock();
cv.notify_one();
// Wait for 'fired' to become true
std::unique_lock<std::mutex> locker(lock);
Expand All @@ -126,34 +123,40 @@ void ThreadedDispatcher::sync()
cond.wait(locker);
}
}
namespace
{
void unlockAndSetFlagToFalse(std::mutex& m, bool& flag)
{
using namespace std;
m.unlock();
flag = false;
}
}

/**
* @brief Perform any work remaining in the queue, then stop accepting new work.
*/
void ThreadedDispatcher::flush()
{
//To ensure all the work that is in the queue is done, we lock a mutex.
//post a job to the queue that unlocks it and stops running further jobs.
//post a job to the queue that signals completion via condition variable.
//Then block here until that's done.
std::unique_lock<std::mutex> runningLocker(m);
if(running)
{
std::mutex m2;
m2.lock();
post(bind(unlockAndSetFlagToFalse, std::ref(m2), std::ref(this->running)));
m2.lock();
m2.unlock();
runningLocker.unlock();
std::mutex flushMutex;
std::condition_variable flushCond;
bool flushed = false;

std::unique_lock<std::mutex> locker(flushMutex);
post([&]() {
std::lock_guard<std::mutex> lock(flushMutex);
flushed = true;
running = false;
flushCond.notify_one();
});

while (!flushed) {
flushCond.wait(locker);
}

stop();
}
else
{
runningLocker.unlock();
AI_LOG_WARN("This dispatcher is no longer running. Ignoring flush request.");
}
}
Expand All @@ -164,7 +167,6 @@ void ThreadedDispatcher::stop()
{
std::unique_lock<std::mutex> lock(m);
running = false;
lock.unlock();
cv.notify_one();
t.join();
}
Expand Down Expand Up @@ -214,4 +216,4 @@ std::function<void ()> ThreadedDispatcher::next()
q.pop_front();
return work;
}
} //AICommon
} //AICommon
5 changes: 4 additions & 1 deletion AppInfrastructure/Common/source/Timer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ using namespace AICommon;

Timer::~Timer()
{
cancel();
try {
cancel();
} catch (const std::exception& e) {
}
Comment on lines +35 to +38
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

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

Timer::~Timer() catches std::exception but ignores it (empty catch block), which can hide real failures during destruction. Either remove the try/catch (cancel() doesn't appear to throw here) or at least log the exception so failures aren't silently swallowed.

Suggested change
try {
cancel();
} catch (const std::exception& e) {
}
cancel();

Copilot uses AI. Check for mistakes.
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down
6 changes: 3 additions & 3 deletions AppInfrastructure/IpcService/source/sdbus/SDBusIpcService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ bool SDBusIpcService::init(const std::string &serviceName,
if (defaultTimeoutMs <= 0)
mDefaultTimeoutUsecs = (25 * 1000 * 1000);
else
mDefaultTimeoutUsecs = (defaultTimeoutMs * 1000);
mDefaultTimeoutUsecs = (static_cast<uint64_t>(defaultTimeoutMs) * 1000);


// eventfd used to wake the poll loop
Expand Down Expand Up @@ -426,7 +426,7 @@ std::shared_ptr<IAsyncReplyGetter> SDBusIpcService::invokeMethod(const Method &m
if (timeoutMs < 0)
timeoutUsecs = mDefaultTimeoutUsecs;
else
timeoutUsecs = (timeoutMs * 1000);
timeoutUsecs = (static_cast<uint64_t>(timeoutMs) * 1000);

// create the reply getter
std::shared_ptr<SDBusAsyncReplyGetter> replyGetter =
Expand Down Expand Up @@ -504,7 +504,7 @@ bool SDBusIpcService::invokeMethod(const Method &method,
if (timeoutMs < 0)
timeoutUsecs = mDefaultTimeoutUsecs;
else
timeoutUsecs = (timeoutMs * 1000);
timeoutUsecs = (static_cast<uint64_t>(timeoutMs) * 1000);

// clear the reply args list
replyArgs.clear();
Expand Down
1 change: 0 additions & 1 deletion AppInfrastructure/Public/Common/Notifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,6 @@ class Notifier : virtual public Polymorphic
{
cv.notify_all();
}
lock.unlock();
}

protected:
Expand Down
2 changes: 1 addition & 1 deletion AppInfrastructure/ReadLine/source/ReadLine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ void ReadLine::commandExecute(const std::string& cmdStr,
}
else if (!errStr.empty())
{
fprintf(stderr, "Ambiguous command '\%s', possible commands: %s %s\n",
fprintf(stderr, "Ambiguous command '%s', possible commands: %s %s\n",
cmdStr.c_str(), cmdRef->name.c_str(), errStr.c_str());
}
else if (cmdRef->handler != nullptr)
Expand Down
4 changes: 4 additions & 0 deletions bundle/lib/source/DobbyBundleConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,13 @@ bool DobbyBundleConfig::isValid() const

uid_t DobbyBundleConfig::userId() const
{
std::lock_guard<std::mutex> locker(mLock);
return mUserId;
}

gid_t DobbyBundleConfig::groupId() const
{
std::lock_guard<std::mutex> locker(mLock);
return mGroupId;
}

Expand Down Expand Up @@ -244,6 +246,7 @@ const std::string& DobbyBundleConfig::rootfsPath() const

bool DobbyBundleConfig::restartOnCrash() const
{
std::lock_guard<std::mutex> locker(mLock);
return mRestartOnCrash;
}

Expand Down Expand Up @@ -286,6 +289,7 @@ const std::map<std::string, Json::Value>& DobbyBundleConfig::legacyPlugins() con

const std::map<std::string, Json::Value>& DobbyBundleConfig::rdkPlugins() const
{
std::lock_guard<std::mutex> locker(mLock);
return mRdkPlugins;
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

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

Same issue as rootfsPath(): returning a const reference after taking an internal lock doesn’t protect callers once the function returns. If concurrent access is expected, return a copy of the map (or provide an API that executes a callback while holding the lock). Otherwise, drop the lock and document immutability.

Suggested change
std::lock_guard<std::mutex> locker(mLock);
return mRdkPlugins;
// Create a thread-local copy of the plugin map so that callers
// receive a reference to per-thread data that is not modified
// concurrently by other threads.
thread_local std::map<std::string, Json::Value> rdkPluginsCopy;
{
std::lock_guard<std::mutex> locker(mLock);
rdkPluginsCopy = mRdkPlugins;
}
return rdkPluginsCopy;

Copilot uses AI. Check for mistakes.
}

Expand Down
1 change: 1 addition & 0 deletions bundle/lib/source/DobbyConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ bool DobbyConfig::changeProcessArgs(const std::string& command)
*/
void DobbyConfig::printCommand() const
{
std::lock_guard<std::mutex> locker(mLock);
std::shared_ptr<rt_dobby_schema> cfg = config();
if (cfg == nullptr)
{
Expand Down
4 changes: 2 additions & 2 deletions bundle/lib/source/DobbySpecConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -917,8 +917,8 @@ bool DobbySpecConfig::processUserNs(const Json::Value& value,
bool DobbySpecConfig::processRtPriority(const Json::Value& value,
ctemplate::TemplateDictionary* dictionary)
{
int rtPriorityDefault;
int rtPriorityLimit;
int rtPriorityDefault = 0;
int rtPriorityLimit = 0;

if (mSpecVersion == SpecVersion::Version1_0)
{
Expand Down
7 changes: 4 additions & 3 deletions bundle/lib/source/DobbyTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,10 @@ DobbyTemplate* DobbyTemplate::instance()
}
}

DobbyTemplate* result = mInstance;
pthread_rwlock_unlock(&mInstanceLock);

return mInstance;
return result;
}

// -----------------------------------------------------------------------------
Expand Down Expand Up @@ -536,7 +537,7 @@ std::string DobbyTemplate::_apply(const ctemplate::TemplateDictionaryInterface*

if (!mTemplateCache->ExpandNoLoad(mTemplateKey,
prettyPrint ? ctemplate::STRIP_WHITESPACE
: ctemplate::STRIP_WHITESPACE,
: ctemplate::DO_NOT_STRIP,
dictionary, nullptr, &result))
{
AI_LOG_ERROR("template cache expand on load failed");
Expand Down Expand Up @@ -654,7 +655,7 @@ bool DobbyTemplate::_applyAt(int dirFd, const std::string& fileName,
bool success = mTemplateCache->ExpandNoLoad(mTemplateKey,
prettyPrint ?
ctemplate::STRIP_WHITESPACE :
ctemplate::STRIP_WHITESPACE,
ctemplate::DO_NOT_STRIP,
dictionary, nullptr, &emitter);
if (!success)
{
Expand Down
98 changes: 51 additions & 47 deletions bundle/tool/source/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ static void parseArgs(const int argc, char **argv)
fprintf(stderr, "Warning: Unknown option `-%c'.\n", optopt);
else
fprintf(stderr, "Warning: Unknown option character `\\x%x'.\n", optopt);

default:
exit(EXIT_FAILURE);
break;
Expand Down Expand Up @@ -228,57 +227,62 @@ static bool generateOciBundle(std::shared_ptr<IDobbySettings> settings,
*/
int main(int argc, char *argv[])
{
printf("Dobby Bundle Generator Tool\n");
parseArgs(argc, argv);
try {
printf("Dobby Bundle Generator Tool\n");
parseArgs(argc, argv);

// Set up so we can read commands
auto readLine = IReadLine::create();
if (!readLine || !readLine->isValid())
{
AI_LOG_ERROR_EXIT("failed to create ReadLine object");
exit(EXIT_FAILURE);
}
// Set up so we can read commands
auto readLine = IReadLine::create();
if (!readLine || !readLine->isValid())
{
AI_LOG_ERROR_EXIT("failed to create ReadLine object");
exit(EXIT_FAILURE);
}

// Can't do any work without a file to process or somewhere to put the
// output
if (inputPath.empty())
{
AI_LOG_ERROR("Must provide a Dobby spec as an input");
exit(EXIT_FAILURE);
}
else if (access(inputPath.c_str(), R_OK) != 0)
{
AI_LOG_ERROR("Cannot access Dobby spec file %s", inputPath.c_str());
exit(EXIT_FAILURE);
}
// Can't do any work without a file to process or somewhere to put the
// output
if (inputPath.empty())
{
AI_LOG_ERROR("Must provide a Dobby spec as an input");
exit(EXIT_FAILURE);
}
else if (access(inputPath.c_str(), R_OK) != 0)
{
AI_LOG_ERROR("Cannot access Dobby spec file %s", inputPath.c_str());
exit(EXIT_FAILURE);
}

// We'll create the directory if it's missing later, so no need to check
// if we can read it
if (outputDirectory.empty())
{
AI_LOG_ERROR("Must provide an output directory");
exit(EXIT_FAILURE);
}
// We'll create the directory if it's missing later, so no need to check
// if we can read it
if (outputDirectory.empty())
{
AI_LOG_ERROR("Must provide an output directory");
exit(EXIT_FAILURE);
}

// Dobby uses a JSON settings file to provide STB-specific settings (e.g GPU)
// Can be left blank (defaylt settings will be used)
else if (!settingsPath.empty() && access(settingsPath.c_str(), R_OK) != 0)
{
AI_LOG_ERROR("Cannot access settings file %s", inputPath.c_str());
exit(EXIT_FAILURE);
}
// Dobby uses a JSON settings file to provide STB-specific settings (e.g GPU)
// Can be left blank (defaylt settings will be used)
else if (!settingsPath.empty() && access(settingsPath.c_str(), R_OK) != 0)
{
AI_LOG_ERROR("Cannot access settings file %s", inputPath.c_str());
exit(EXIT_FAILURE);
}

AI_LOG_INFO("Parsing Dobby spec file %s\n", inputPath.c_str());
AI_LOG_INFO("Generating Bundle in directory: %s\n", outputDirectory.c_str());
AI_LOG_INFO("Parsing Dobby spec file %s\n", inputPath.c_str());
AI_LOG_INFO("Generating Bundle in directory: %s\n", outputDirectory.c_str());

// Get settings from the provided json file
auto settings = readSettings();
auto utils = std::make_shared<DobbyUtils>();
// Get settings from the provided json file
auto settings = readSettings();
auto utils = std::make_shared<DobbyUtils>();

// Now we can do some actual work
generateOciBundle(settings, utils, inputPath, outputDirectory);
// Now we can do some actual work
generateOciBundle(settings, utils, inputPath, outputDirectory);

// And we're done
AICommon::termLogging();
return EXIT_SUCCESS;
}
// And we're done
AICommon::termLogging();
return EXIT_SUCCESS;
} catch (const std::exception& e) {
AI_LOG_ERROR_EXIT("Unhandled exception in main: %s\n", e.what());
exit(EXIT_FAILURE);
}
}
1 change: 0 additions & 1 deletion client/lib/source/DobbyProxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,6 @@ DobbyProxy::~DobbyProxy()
{
std::unique_lock<std::mutex> locker(mStateChangeLock);
mStateChangeQueue.emplace_back(StateChangeEvent::Terminate);
locker.unlock();

mStateChangeCond.notify_all();
mStateChangeThread.join();
Expand Down
Loading
Loading