Conversation
There was a problem hiding this comment.
Pull request overview
This PR targets faster shutdowns in lightNVR by reducing waits during teardown and avoiding waiting on components that were never registered with the shutdown coordinator.
Changes:
- Attempts to wake sleeping background threads during shutdown using
pthread_kill()so they can exit promptly. - Adjusts shutdown coordinator initialization/registration so
wait_for_all_components_stopped()doesn’t wait when nothing was registered. - Removes a couple of duplicate shutdown log lines and tweaks a startup wait loop sleep interval.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| src/web/api_handlers_health.c | Wakes health-check thread during shutdown to reduce stop latency. |
| src/video/mp4_writer_thread.c | Reduces CPU usage in thread-start wait loop by increasing sleep interval. |
| src/telemetry/stream_metrics.c | Wakes metrics sampler thread during shutdown for faster exit. |
| src/database/db_recordings_sync.c | Wakes recordings sync thread during shutdown for faster exit. |
| src/core/shutdown_coordinator.c | Initializes coordinator as “all stopped” until a component registers; improves logging loop stability. |
| src/core/mqtt_client.c | Wakes MQTT HA background threads during stop/failure cleanup. |
| src/core/main.c | Removes duplicate shutdown log lines around MP4/HLS cleanup. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| g_health_thread_running = false; | ||
| pthread_kill(g_health_check_thread, SIGALRM); | ||
| sched_yield(); | ||
|
|
||
| // Use portable polling approach with timeout (5 seconds) |
| if (g_sampler_running) { | ||
| g_sampler_running = false; | ||
| pthread_kill(g_sampler_thread, SIGALRM); | ||
| sched_yield(); | ||
|
|
||
| pthread_join(g_sampler_thread, NULL); |
| sync_thread.running = false; | ||
| pthread_mutex_unlock(&sync_thread.mutex); | ||
| pthread_kill(sync_thread.thread, SIGALRM); | ||
|
|
||
| // Wait for thread to exit |
| log_error("MQTT HA: Failed to create motion timeout thread"); | ||
| // Signal any already-started HA service threads to stop | ||
| ha_services_running = false; | ||
| pthread_kill(ha_snapshot_thread, SIGALRM); | ||
| sched_yield(); | ||
|
|
| ha_services_running = false; | ||
| pthread_kill(ha_snapshot_thread, SIGALRM); | ||
| pthread_kill(ha_motion_thread, SIGALRM); | ||
| sched_yield(); |
| pthread_kill(g_health_check_thread, SIGALRM); | ||
| sched_yield(); | ||
|
|
| pthread_kill(g_health_check_thread, SIGALRM); | ||
| sched_yield(); |
| pthread_kill(g_sampler_thread, SIGALRM); | ||
| sched_yield(); | ||
|
|
| pthread_kill(ha_snapshot_thread, SIGALRM); | ||
| sched_yield(); | ||
|
|
|
I thought |
Shutting down lightNVR can take 15-20 seconds, which sometimes makes development more tedious than necessary. This PR cleans up some of the more egregious shutdown delays by signalling threads so they wake up from
sleep()and properly initializing the shutdown manager so it doesn't wait for components that were never registered. A few duplicate log lines are also removed.