From 476ce3ed6f92040e0583b7aa7b961ba06d06fe25 Mon Sep 17 00:00:00 2001 From: Patryk Kubiak Date: Sun, 11 Oct 2026 21:00:13 +0200 Subject: [PATCH] Dmod_Run: do not hold the module's mutex while its main() runs Dmod_Run() kept Context->Mutex locked from before Dmod_Init() until after Dmod_Deinit(), i.e. for as long as the application runs. Everybody who locks it meanwhile - Dmod_BeginUsage() / _EndUsage(), Dmod_Enable(), ... - waited for the application to end, lending it their priority all the time (FreeRTOS mutexes inherit priority; it is given back only when the holder releases every mutex it holds): on dmod-boot every service started by systemd (priority 4) ran at 4 instead of its own DMOD_PRIORITY - a view being drawn by dmview starved an MP3 decoder of priority 2 (the car HMI played choppy). Found on the board: every service held one recursive mutex, its context's, at priority 4 over a base of 0 or 1. The mutex is released for Dmod_Main() and taken again for the deinit; Context->Running (set under it) still keeps a second Dmod_Run() out, and Dmod_Unload() still refuses a running module. Co-Authored-By: Claude Opus 5.5 --- src/system/dmod_system.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/system/dmod_system.c b/src/system/dmod_system.c index 4a83a52..6f48537 100644 --- a/src/system/dmod_system.c +++ b/src/system/dmod_system.c @@ -1384,7 +1384,18 @@ int Dmod_Run( Dmod_Context_t* Context, int argc, char *argv[] ) return -ENOEXEC; } + // Not held while main() runs: what the module does may take as long as it + // runs, and whoever asks the module something meanwhile (Dmod_BeginUsage(), + // Dmod_Enable(), ...) would wait that long - lending it its priority all + // that time (a mutex's priority inheritance), so a service started by a + // high-priority manager kept that priority for good. `Running` keeps a + // second Dmod_Run() out, and Dmod_Unload() refuses a running module. + Dmod_Mutex_Unlock(Context->Mutex); result = Dmod_Main( Context, argc, argv ); + if( Dmod_Mutex_Lock(Context->Mutex) != 0 ) + { + DMOD_LOG_ERROR("Module %s: cannot lock its mutex after main()\n", Dmod_Context_GetModuleName( Context )); + } Dmod_Event_ModuleStopped( Context ); Context->Running = false;