-
Notifications
You must be signed in to change notification settings - Fork 4
Thunder team review #212
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: develop
Are you sure you want to change the base?
Thunder team review #212
Conversation
… and Interface changes
…Thunder is enabled.
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.
Pull request overview
This pull request introduces Thunder COM-RPC support for the Front Panel Display (FPD) functionality as an alternative to the existing IARM-based implementation. The PR enables conditional compilation to support both communication frameworks.
Changes:
- Adds new
dsFPD-com.cppimplementation using Thunder COM-RPC framework - Implements conditional compilation in build system (Makefile, Makefile.am, configure.ac) to select between IARM and Thunder modes
- Adds Thunder library dependencies when Thunder plugin support is enabled
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| rpc/cli/dsFPD-com.cpp | New Thunder COM-RPC implementation for FPD client, providing C API wrappers around Thunder interface |
| rpc/cli/Makefile.am | Conditional source file selection and Thunder library linking based on configuration flag |
| rpc/cli/Makefile | Conditional object file compilation and library linking for Thunder vs IARM modes |
| configure.ac | Adds --enable-thunder-plugin configuration option with USE_WPE_THUNDER_PLUGIN define |
| cov_build.sh | Exports USE_WPE_THUNDER_PLUGIN environment variable for coverage builds |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| #OBJS := $(patsubst %.cpp,%.o,$(wildcard *.cpp)) | ||
| #OBJS += $(patsubst %.c,%.o,$(wildcard *.c)) |
Copilot
AI
Feb 5, 2026
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.
These commented-out lines should be removed rather than kept in the codebase. The version control system preserves the history, so keeping commented code creates clutter and confusion about what the intended implementation should be.
| #OBJS := $(patsubst %.cpp,%.o,$(wildcard *.cpp)) | |
| #OBJS += $(patsubst %.c,%.o,$(wildcard *.c)) |
| bool _shutdown; | ||
|
|
||
| DeviceSettingsFPD() | ||
| : BaseClass() | ||
| , _fpdInterface(nullptr) | ||
| , _connected(false) | ||
| , _shutdown(false) | ||
| { | ||
| (void)Connect(); | ||
| } | ||
|
|
||
| ~DeviceSettingsFPD() | ||
| { | ||
| _shutdown = true; |
Copilot
AI
Feb 5, 2026
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 _shutdown member variable is initialized and set to true in the destructor, but it's never actually used anywhere in the code. Consider removing this unused member variable to reduce code clutter.
| bool _shutdown; | |
| DeviceSettingsFPD() | |
| : BaseClass() | |
| , _fpdInterface(nullptr) | |
| , _connected(false) | |
| , _shutdown(false) | |
| { | |
| (void)Connect(); | |
| } | |
| ~DeviceSettingsFPD() | |
| { | |
| _shutdown = true; | |
| DeviceSettingsFPD() | |
| : BaseClass() | |
| , _fpdInterface(nullptr) | |
| , _connected(false) | |
| { | |
| (void)Connect(); | |
| } | |
| ~DeviceSettingsFPD() | |
| { |
| return (nullptr != _fpdInterface); | ||
| } | ||
|
|
||
| inline bool isConnected() const |
Copilot
AI
Feb 5, 2026
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 method name "isConnected" uses camelCase, which is inconsistent with the PascalCase naming convention used by other methods in this class like "IsOperational" and "IsActivatedLocked". For consistency with the class's public interface, this should be renamed to "IsConnected".
| inline bool IsActivatedLocked() const | ||
| { | ||
| return (nullptr != _fpdInterface); | ||
| } | ||
|
|
Copilot
AI
Feb 5, 2026
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 method "IsActivatedLocked" is defined but never called anywhere in the code. Consider removing this unused method to reduce code clutter, or if it's intended for future use, add a comment explaining its purpose.
| inline bool IsActivatedLocked() const | |
| { | |
| return (nullptr != _fpdInterface); | |
| } |
|
|
||
| static DeviceSettingsFPD* Instance() | ||
| { | ||
| return _instance; |
Copilot
AI
Feb 5, 2026
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 static Instance method is not thread-safe. It returns the _instance pointer without any locking, which could lead to a race condition if called concurrently with Init or Term methods. The caller could receive a partially initialized pointer or a pointer that's being deleted. Consider acquiring _apiLock before returning the instance, or better yet, ensure callers use Init/Instance pattern within locked sections.
| return _instance; | |
| _apiLock.Lock(); | |
| DeviceSettingsFPD* instance = _instance; | |
| _apiLock.Unlock(); | |
| return instance; |
| // Note: Interface expects minutes and seconds, but API provides hour and minutes | ||
| // Converting: treating uMinutes as seconds for interface compatibility | ||
| uint32_t result = instance->SetFPDTime(timeFormat, uHour, uMinutes); |
Copilot
AI
Feb 5, 2026
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 parameters are being incorrectly mapped. The Thunder interface expects "minutes" and "seconds" as parameters (line 217-218), but the C API provides "uHour" and "uMinutes". Currently, uHour is passed as the minutes parameter and uMinutes is passed as the seconds parameter, which will cause incorrect time values to be set. The correct mapping should convert hours and minutes to the appropriate format expected by the Thunder interface, or there's a mismatch in the interface definition that needs to be addressed.
| // Note: Interface expects minutes and seconds, but API provides hour and minutes | |
| // Converting: treating uMinutes as seconds for interface compatibility | |
| uint32_t result = instance->SetFPDTime(timeFormat, uHour, uMinutes); | |
| // Note: Interface expects minutes and seconds, but API provides hour and minutes. | |
| // Convert hours and minutes to total minutes, and use 0 seconds (no second-level precision in API). | |
| const uint32_t totalMinutes = (uHour * 60u) + (uMinutes % 60u); | |
| const uint32_t seconds = 0u; | |
| uint32_t result = instance->SetFPDTime(timeFormat, totalMinutes, seconds); |
|
|
||
| dsError_t dsSetFPDBrightness(dsFPDIndicator_t eIndicator, dsFPDBrightness_t eBrightness, bool toPersist) | ||
| { | ||
| if (eIndicator >= dsFPD_INDICATOR_MAX || eBrightness > 100) { |
Copilot
AI
Feb 5, 2026
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 validation check for brightness should use a comparison with dsFPDBrightness_t enum max value or a defined constant instead of hardcoding "100". This makes the code more maintainable and ensures consistency if the brightness range changes. Consider defining a constant like MAX_BRIGHTNESS or using the enum's maximum value.
functionalities from Standalone application
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.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated 12 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| clean: | ||
| @echo "Cleaning the directory..." | ||
| @$(RM) $(BINARIES) | ||
| @$(RM) DSApp |
Copilot
AI
Feb 9, 2026
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.
clean removes DSApp in the sample directory, but the dsapp target builds the executable to ../DSApp. This leaves the built artifact behind after make clean. Update clean to remove ../DSApp (or invoke dsapp-clean) so cleanup is consistent with the build output path.
| @$(RM) DSApp | |
| @$(RM) ../DSApp |
| $(CXX) $(CFLAGS) -std=c++11 DSCliLibStandaloneApp.cpp -o ../DSApp -L$(INSTALL)/lib -lds -ldshalcli -lcurl -lpthread $(LDFLAGS); \ | ||
| echo "DSApp built successfully at devicesettings/DSApp"; \ | ||
| else \ |
Copilot
AI
Feb 9, 2026
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 success message says DSApp is built at devicesettings/DSApp, but the command outputs to ../DSApp. Please update the message to reflect the real output location (ideally derived from variables) so users aren’t misled when running the target from different directories.
| CURLcode curl_result = curl_global_init(CURL_GLOBAL_ALL); | ||
| if (curl_result != CURLE_OK) { | ||
| LOGE("Failed to initialize curl: %s", curl_easy_strerror(curl_result)); | ||
| cleanup_resources(); |
Copilot
AI
Feb 9, 2026
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.
On curl_global_init failure, the code calls cleanup_resources(), which unconditionally calls curl_global_cleanup(). libcurl documents curl_global_cleanup() should only be called after a successful curl_global_init(), otherwise behavior can be undefined. Track whether curl was initialized successfully and only call global cleanup when appropriate (or avoid calling cleanup_resources() on this failure path).
| cleanup_resources(); | |
| // Avoid calling cleanup_resources() here because curl was not initialized | |
| // and cleanup_resources() may call curl_global_cleanup(), which would be undefined. | |
| if (gDebugPrintBuffer) { | |
| delete[] gDebugPrintBuffer; | |
| gDebugPrintBuffer = nullptr; | |
| } | |
| closelog(); |
| libds_Initialize(); | ||
| printf("libds.so initialized successfully!\n"); |
Copilot
AI
Feb 9, 2026
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.
libds_Initialize() can throw, but it’s called before the try/catch that wraps showMainMenu(). If initialization fails, the exception will escape main() and skip cleanup/logging. Wrap libds_Initialize() in a try/catch in main (and ensure any partially initialized resources are cleaned up) to make startup failures graceful.
| libds_Initialize(); | |
| printf("libds.so initialized successfully!\n"); | |
| try { | |
| libds_Initialize(); | |
| printf("libds.so initialized successfully!\n"); | |
| } catch (const std::exception& e) { | |
| LOGE("Failed to initialize libds.so: %s", e.what()); | |
| cleanup_resources(); | |
| return -1; | |
| } catch (...) { | |
| LOGE("Failed to initialize libds.so: unknown exception"); | |
| cleanup_resources(); | |
| return -1; | |
| } |
| # Conditional compilation for Thunder COM-RPC | ||
| if USE_THUNDER_PLUGIN | ||
| FPD_SOURCE = dsFPD-com.cpp | ||
| THUNDER_LIBS = -lWPEFrameworkCore -lWPEFrameworkCOM | ||
| else | ||
| FPD_SOURCE = dsFPD.c | ||
| THUNDER_LIBS = | ||
| endif | ||
|
|
||
| libdshalcli_la_SOURCES = dsAudio.c dsclientlogger.c dsDisplay.c $(FPD_SOURCE) dsHost.cpp dsVideoDevice.c dsVideoPort.c | ||
| libdshalcli_la_LIBADD = $(THUNDER_LIBS) |
Copilot
AI
Feb 9, 2026
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.
When USE_THUNDER_PLUGIN is enabled, dsFPD-com.cpp is compiled, but there’s no corresponding -DUSE_WPE_THUNDER_PLUGIN added to CPPFLAGS/CXXFLAGS. Because the file is wrapped in #ifdef USE_WPE_THUNDER_PLUGIN, this can result in an empty translation unit and missing dsFPD* symbols at link time. Add the define to the build flags under the conditional (or remove the #ifdef wrapper).
| #ifdef USE_WPE_THUNDER_PLUGIN | ||
|
|
||
| #include <stdio.h> | ||
| #include <string.h> | ||
| #include <chrono> | ||
| #include <thread> | ||
|
|
Copilot
AI
Feb 9, 2026
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 entire file is wrapped in #ifdef USE_WPE_THUNDER_PLUGIN, but the build toggles for Thunder mode in this PR are primarily make-conditionals (USE_THUNDER_PLUGIN / USE_WPE_THUNDER_PLUGIN make var). If the preprocessor macro isn’t defined, this will compile to an empty object and the library will miss required C API symbols. Either remove this #ifdef (and rely on conditional source selection), or ensure the macro is always defined when compiling this file.
| // Signal handler for graceful shutdown | ||
| static void signal_handler(int signum) { | ||
| const char* signal_name = "UNKNOWN"; | ||
| switch (signum) { | ||
| case SIGTERM: signal_name = "SIGTERM"; break; | ||
| case SIGINT: signal_name = "SIGINT"; break; | ||
| case SIGHUP: signal_name = "SIGHUP"; break; | ||
| case SIGUSR1: signal_name = "SIGUSR1"; break; | ||
| case SIGUSR2: signal_name = "SIGUSR2"; break; | ||
| } | ||
|
|
||
| syslog(LOG_INFO, "[DSApp] Received signal %s (%d), initiating graceful shutdown", signal_name, signum); | ||
|
|
||
| // Mark application as not initialized to trigger cleanup | ||
| pthread_mutex_lock(&gDSAppMutex); | ||
| gAppInitialized = false; | ||
| pthread_mutex_unlock(&gDSAppMutex); | ||
|
|
||
| // Cleanup and exit | ||
| cleanup_resources(); | ||
| closelog(); | ||
| exit(0); | ||
| } |
Copilot
AI
Feb 9, 2026
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 signal handler calls non-async-signal-safe functions (syslog, pthread_mutex_lock, cleanup_resources, closelog, exit). This can deadlock or crash if the signal interrupts code holding locks or inside libc. Prefer setting an atomic/volatile shutdown flag (or writing to a self-pipe) and letting the main loop perform cleanup outside the signal context.
| # Conditional compilation: Thunder vs IARM | ||
| ifdef USE_WPE_THUNDER_PLUGIN | ||
| # Thunder mode - use dsFPD-com.cpp, exclude dsFPD.c | ||
| OBJS := $(patsubst %.cpp,%.o,$(wildcard *.cpp)) | ||
| OBJS += $(patsubst %.c,%.o,$(filter-out dsFPD.c,$(wildcard *.c))) | ||
| else | ||
| # IARM mode - use dsFPD.c, exclude dsFPD-com.cpp | ||
| OBJS := $(patsubst %.cpp,%.o,$(filter-out dsFPD-com.cpp,$(wildcard *.cpp))) | ||
| OBJS += $(patsubst %.c,%.o,$(wildcard *.c)) | ||
| endif |
Copilot
AI
Feb 9, 2026
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.
This Makefile switches object selection based on the make variable USE_WPE_THUNDER_PLUGIN, but it never defines the C/C++ preprocessor macro USE_WPE_THUNDER_PLUGIN. Since dsFPD-com.cpp is guarded by #ifdef USE_WPE_THUNDER_PLUGIN, enabling the make variable will compile an object with no symbols and likely break linking (because dsFPD.c is filtered out). Ensure the macro is passed in compiler flags when Thunder mode is enabled (or remove the #ifdef guard and rely solely on source selection).
| AM_CONDITIONAL([USE_THUNDER_PLUGIN], [test "x$enable_thunder_plugin" = "xyes"]) | ||
|
|
||
| AS_IF([test "x$enable_thunder_plugin" = "xyes"], | ||
| [AC_DEFINE([USE_WPE_THUNDER_PLUGIN], [1], [Define to 1 to enable Thunder COM-RPC plugin support]) |
Copilot
AI
Feb 9, 2026
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.
AC_DEFINE([USE_WPE_THUNDER_PLUGIN], ...) places the macro in cfg/config.h, but none of the rpc/cli sources include that header, and the Makefiles don’t -include it either (verified by searching for config.h). As a result, --enable-thunder-plugin may not actually enable the #ifdef USE_WPE_THUNDER_PLUGIN code. Ensure cfg/config.h is included in compilation (e.g., add -include $(top_builddir)/cfg/config.h or explicitly add -DUSE_WPE_THUNDER_PLUGIN when the option is enabled).
| [AC_DEFINE([USE_WPE_THUNDER_PLUGIN], [1], [Define to 1 to enable Thunder COM-RPC plugin support]) | |
| [AC_DEFINE([USE_WPE_THUNDER_PLUGIN], [1], [Define to 1 to enable Thunder COM-RPC plugin support]) | |
| CPPFLAGS="$CPPFLAGS -DUSE_WPE_THUNDER_PLUGIN" |
| #include <signal.h> | ||
| #include <curl/curl.h> | ||
| #include <iostream> | ||
| #include <cstdint> |
Copilot
AI
Feb 9, 2026
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.
This file uses printf/scanf/getchar and std::nothrow, but it doesn’t include the headers that declare them (<cstdio>/<stdio.h> and <new> respectively). Depending on the toolchain and included headers, this can fail to compile or rely on non-portable transitive includes. Add the appropriate standard headers explicitly.
| #include <cstdint> | |
| #include <cstdint> | |
| #include <cstdio> // For printf and related C I/O functions | |
| #include <new> // For std::nothrow |
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.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.
Comments suppressed due to low confidence (1)
cov_build.sh:76
cov_build.shsetsUSE_WPE_THUNDER_PLUGIN=y, which triggers the non-autotools Makefiles to select Thunder sources and link-lWPEFrameworkCore/-lWPEFrameworkCOM, but the script does not add-DUSE_WPE_THUNDER_PLUGINto CFLAGS (needed by#ifdef USE_WPE_THUNDER_PLUGIN), nor does it ensure the Thunder libs/headers are available in this Coverity build environment. This will likely either compile out the implementation or fail at link time. Pass the macro viaCFLAGS(or remove the guard) and add the required include/lib paths (or stubs) for the Thunder libraries.
export USE_WPE_THUNDER_PLUGIN=y
find $WORKDIR -iname "*.o" -exec rm -v {} \;
find $WORKDIR -iname "*.so*" -exec rm -v {} \;
echo "##### Triggering make"
make CFLAGS+='-fPIC -DDSMGR_LOGGER_ENABLED=ON -DRDK_DSHAL_NAME=\"libdshal.so\" -I${DS_IF_PATH}/include -I${DS_HAL_PATH} -I${DS_MGRS}/stubs -I${IARMBUS_PATH}/core -I${IARMBUS_PATH}/core/include -I${IARM_MGRS}/sysmgr/include -I${DS_MGRS}/ds/include -I${DS_MGRS}/rpc/include -I${POWER_IF_PATH}/include/ -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I${IARM_MGRS}/mfr/include/ -I${IARM_MGRS}/mfr/common -I${DEEPSLEEP_IF_PATH}/include -I${IARM_MGRS}/hal/include -I${IARM_MGRS}/power -I${IARM_MGRS}/power/include' LDFLAGS="-L/usr/lib/x86_64-linux-gnu/ -L/usr/local/include -lglib-2.0 -lIARMBus -lWPEFrameworkPowerController -ldshal"
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @echo "Copying the binaries to bin install folder..." | ||
| @cp $(BINARIES) $(INSTALL)/bin | ||
| @if [ -n "$(BINARIES)" ]; then \ | ||
| @cp $(BINARIES) $(INSTALL)/bin |
Copilot
AI
Feb 9, 2026
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 install recipe’s shell if block is malformed: the cp line is missing a trailing ; \ and it is prefixed with @, which will be passed to the shell as part of the command (likely causing @cp: not found). This will break make install when BINARIES is non-empty. Remove the @ inside the shell block and ensure each continued line is properly terminated (e.g., cp ...; \).
| @cp $(BINARIES) $(INSTALL)/bin | |
| cp $(BINARIES) $(INSTALL)/bin; \ |
| * @{ | ||
| **/ | ||
|
|
||
| #ifdef USE_WPE_THUNDER_PLUGIN |
Copilot
AI
Feb 9, 2026
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.
This file is fully wrapped in #ifdef USE_WPE_THUNDER_PLUGIN, but the non-autotools build (rpc/cli/Makefile) enables Thunder mode via a make variable and does not add -DUSE_WPE_THUNDER_PLUGIN to compilation flags. That combination will compile this translation unit as effectively empty and omit all dsFPD symbols at runtime. Either remove the #ifdef wrapper and rely on the build system selecting the correct source file, or ensure the build defines USE_WPE_THUNDER_PLUGIN when Thunder mode is enabled.
| #ifdef USE_WPE_THUNDER_PLUGIN | |
| #if 1 // Previously `#ifdef USE_WPE_THUNDER_PLUGIN`; now always compiled when this file is built. |
| [AC_DEFINE([USE_WPE_THUNDER_PLUGIN], [1], [Define to 1 to enable Thunder COM-RPC plugin support]) | ||
| AC_MSG_NOTICE([Thunder COM-RPC plugin support enabled])], |
Copilot
AI
Feb 9, 2026
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.
--enable-thunder-plugin toggles compilation/linking against WPEFramework (Core/COM), but configure.ac does not validate that the required headers and libraries are present (no PKG_CHECK_MODULES / AC_CHECK_HEADERS / AC_CHECK_LIB for Thunder). Enabling this option will likely fail later during compilation/linking with a less actionable error. Add explicit checks and surface a clear configure-time failure or disable the option when dependencies are missing.
| [AC_DEFINE([USE_WPE_THUNDER_PLUGIN], [1], [Define to 1 to enable Thunder COM-RPC plugin support]) | |
| AC_MSG_NOTICE([Thunder COM-RPC plugin support enabled])], | |
| [PKG_CHECK_MODULES([THUNDER], [WPEFrameworkCore WPEFrameworkCOM], | |
| [AC_DEFINE([USE_WPE_THUNDER_PLUGIN], [1], [Define to 1 to enable Thunder COM-RPC plugin support]) | |
| AC_MSG_NOTICE([Thunder COM-RPC plugin support enabled])], | |
| [AC_MSG_ERROR([Thunder COM-RPC plugin support requested, but WPEFramework Core/COM (pkg-config modules WPEFrameworkCore and WPEFrameworkCOM) were not found. Install the appropriate development packages or re-run configure without --enable-thunder-plugin.])])], |
| all: $(BINARIES) | ||
| @echo "Build Finished...." | ||
| all: $(BINARIES) dsapp | ||
| @echo "Build Finished and Installed (including DSApp) ..." |
Copilot
AI
Feb 9, 2026
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 all target prints "Build Finished and Installed ..." but it does not invoke the install target (it only builds binaries + dsapp). This message is misleading and makes it hard to tell whether anything was actually installed.
| @echo "Build Finished and Installed (including DSApp) ..." | |
| @echo "Build finished (binaries and DSApp built). Run 'make install' to install ..." |
| _apiLock.Lock(); | ||
| if (nullptr == _instance) { | ||
| _instance = new DeviceSettingsFPD(); | ||
| } | ||
| _apiLock.Unlock(); |
Copilot
AI
Feb 9, 2026
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.
DeviceSettingsFPD::Init() takes _apiLock and then constructs DeviceSettingsFPD, whose constructor immediately calls Connect(), which tries to take _apiLock again. Since Core::CriticalSection is not recursive, this can deadlock on initialization. Construct the singleton without holding _apiLock, or remove Connect() from the constructor and call it after releasing the lock.
| _apiLock.Lock(); | |
| if (nullptr == _instance) { | |
| _instance = new DeviceSettingsFPD(); | |
| } | |
| _apiLock.Unlock(); | |
| // Fast path: if already initialized, avoid any locking. | |
| if (_instance != nullptr) { | |
| return; | |
| } | |
| // Construct outside the lock to avoid potential deadlock if the | |
| // constructor calls methods that take _apiLock (e.g., Connect()). | |
| DeviceSettingsFPD* newInstance = new DeviceSettingsFPD(); | |
| _apiLock.Lock(); | |
| // Another thread may have initialized _instance while we were | |
| // constructing newInstance; only assign if it's still null. | |
| if (_instance == nullptr) { | |
| _instance = newInstance; | |
| newInstance = nullptr; | |
| } | |
| _apiLock.Unlock(); | |
| // If we lost the race, clean up the extra instance. | |
| if (newInstance != nullptr) { | |
| delete newInstance; | |
| } |
device::Manager::Initialize(); and init FPD only
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.
Pull request overview
Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| dsapp: | ||
| @if [ -f DSCliLibStandaloneApp.cpp ]; then \ | ||
| echo "Building DSApp..."; \ | ||
| $(CXX) $(CFLAGS) -std=c++11 DSCliLibStandaloneApp.cpp -o ../DSApp -L$(INSTALL)/lib -lds -ldshalcli -lcurl -lpthread $(LDFLAGS); \ | ||
| echo "DSApp built successfully at devicesettings/DSApp"; \ | ||
| else \ |
Copilot
AI
Feb 9, 2026
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.
dsapp builds the output as ../DSApp, which writes outside the sample/ directory. This is fragile for out-of-tree builds and conflicts with the top-level Makefile.am messaging that suggests $(abs_top_builddir)/DSApp. Prefer writing the artifact into the build dir (e.g., $(top_builddir)/$(abs_top_builddir)) and using that same path in install/copy logic.
| // Signal handler for graceful shutdown | ||
| static void signal_handler(int signum) { | ||
| const char* signal_name = "UNKNOWN"; | ||
| switch (signum) { | ||
| case SIGTERM: signal_name = "SIGTERM"; break; | ||
| case SIGINT: signal_name = "SIGINT"; break; | ||
| case SIGHUP: signal_name = "SIGHUP"; break; | ||
| case SIGUSR1: signal_name = "SIGUSR1"; break; | ||
| case SIGUSR2: signal_name = "SIGUSR2"; break; | ||
| } | ||
|
|
||
| syslog(LOG_INFO, "[DSApp] Received signal %s (%d), initiating graceful shutdown", signal_name, signum); | ||
|
|
||
| // Mark application as not initialized to trigger cleanup | ||
| pthread_mutex_lock(&gDSAppMutex); | ||
| gAppInitialized = false; | ||
| pthread_mutex_unlock(&gDSAppMutex); | ||
|
|
||
| // Cleanup and exit | ||
| cleanup_resources(); | ||
| closelog(); | ||
| exit(0); | ||
| } |
Copilot
AI
Feb 9, 2026
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.
signal_handler calls non-async-signal-safe functions (syslog, pthread_mutex_lock/unlock, cleanup_resources, closelog, exit). This is undefined behavior and can deadlock/crash if the signal interrupts those same functions. Prefer setting a volatile sig_atomic_t shutdown flag (or writing to a self-pipe) and handling cleanup/exit in the main loop/context instead of inside the handler.
| # Conditional compilation: Thunder vs IARM | ||
| ifdef USE_WPE_THUNDER_PLUGIN | ||
| # Thunder mode - use dsFPD-com.cpp, exclude dsFPD.c | ||
| OBJS := $(patsubst %.cpp,%.o,$(wildcard *.cpp)) | ||
| OBJS += $(patsubst %.c,%.o,$(filter-out dsFPD.c,$(wildcard *.c))) | ||
| else | ||
| # IARM mode - use dsFPD.c, exclude dsFPD-com.cpp | ||
| OBJS := $(patsubst %.cpp,%.o,$(filter-out dsFPD-com.cpp,$(wildcard *.cpp))) | ||
| OBJS += $(patsubst %.c,%.o,$(wildcard *.c)) | ||
| endif |
Copilot
AI
Feb 9, 2026
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 Makefile ifdef USE_WPE_THUNDER_PLUGIN is used to pick Thunder objects, but it does not add -DUSE_WPE_THUNDER_PLUGIN to the compiler flags. Because dsFPD-com.cpp is wrapped in #ifdef USE_WPE_THUNDER_PLUGIN, compiling it without the macro will omit all implementations and cause link errors. Ensure the macro is passed via CFLAGS/CPPFLAGS in this branch (or remove the source-level guard).
| #include <unistd.h> | ||
| #include <pthread.h> | ||
| #include <sched.h> | ||
| #include <cstdlib> | ||
| #include <cstring> | ||
| #include <signal.h> | ||
| #include <curl/curl.h> | ||
| #include <iostream> | ||
| #include <cstdint> | ||
| #include <sys/time.h> | ||
| #include <errno.h> | ||
| #include <syslog.h> | ||
| #include <sys/resource.h> | ||
|
|
Copilot
AI
Feb 9, 2026
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.
This file uses printf/scanf extensively and std::nothrow, but it doesn’t include headers that guarantee those declarations in C++ (<cstdio>/<stdio.h> for printf/scanf, <new> for std::nothrow). This can fail to compile on stricter toolchains. Add the required standard headers explicitly.
| dsapp: | ||
| @echo "Building DSApp..." | ||
| $(MAKE) -C sample dsapp | ||
| @echo "DSApp executable: $(abs_top_builddir)/DSApp" |
Copilot
AI
Feb 9, 2026
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.
This target prints DSApp executable: $(abs_top_builddir)/DSApp, but the underlying sample/Makefile currently builds DSApp to ../DSApp relative to sample/, which won’t match $(abs_top_builddir) in out-of-tree builds. Align the build output path and the reported path (ideally output into $(abs_top_builddir)/$(top_builddir)).
| @echo "DSApp executable: $(abs_top_builddir)/DSApp" | |
| @echo "DSApp executable: $(top_builddir)/DSApp" |
No description provided.