-
Notifications
You must be signed in to change notification settings - Fork 0
Isolate watchdog restart to only the timed-out camera #1
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -352,8 +352,6 @@ void cls_motapp::ntc() | |||||||||||||||||||||||||||||||||||||||||||||||||
| /* Check for whether any cams are locked */ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| void cls_motapp::watchdog(uint camindx) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| int indx; | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| if (cam_list[camindx]->handler_running == false) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -367,33 +365,31 @@ void cls_motapp::watchdog(uint camindx) | |||||||||||||||||||||||||||||||||||||||||||||||||
| , _("Camera %d - Watchdog timeout.") | ||||||||||||||||||||||||||||||||||||||||||||||||||
| , cam_list[camindx]->cfg->device_id); | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| /* Shut down all the cameras */ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| for (indx=0; indx<cam_cnt; indx++) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| cam_list[indx]->event_stop = true; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| pthread_mutex_unlock(&mutex_camlst); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| pthread_mutex_unlock(&mutex_post); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| pthread_mutex_unlock(&dbse->mutex_dbse); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| pthread_mutex_unlock(&cam_list[indx]->stream.mutex); | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| if ((cam_list[indx]->camera_type == CAMERA_TYPE_NETCAM) && | ||||||||||||||||||||||||||||||||||||||||||||||||||
| (cam_list[indx]->netcam != nullptr)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| pthread_mutex_unlock(&cam_list[indx]->netcam->mutex); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| pthread_mutex_unlock(&cam_list[indx]->netcam->mutex_pktarray); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| pthread_mutex_unlock(&cam_list[indx]->netcam->mutex_transfer); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| cam_list[indx]->netcam->handler_stop = true; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| if ((cam_list[indx]->camera_type == CAMERA_TYPE_NETCAM) && | ||||||||||||||||||||||||||||||||||||||||||||||||||
| (cam_list[indx]->netcam_high != nullptr)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| pthread_mutex_unlock(&cam_list[indx]->netcam_high->mutex); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| pthread_mutex_unlock(&cam_list[indx]->netcam_high->mutex_pktarray); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| pthread_mutex_unlock(&cam_list[indx]->netcam_high->mutex_transfer); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| cam_list[indx]->netcam_high->handler_stop = true; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| /* Shut down only the timed-out camera */ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| cam_list[camindx]->event_stop = true; | ||||||||||||||||||||||||||||||||||||||||||||||||||
| pthread_mutex_unlock(&mutex_camlst); | ||||||||||||||||||||||||||||||||||||||||||||||||||
| pthread_mutex_unlock(&mutex_post); | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| pthread_mutex_unlock(&mutex_post); |
Copilot
AI
Mar 25, 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.
pthread_mutex_unlock(&dbse->mutex_dbse) is undefined behavior unless the watchdog thread owns that mutex. If the intent is to prevent the app from deadlocking when a camera thread hangs inside DB operations, consider using timeouts/timed locks around DB work or moving DB interaction to a dedicated thread/queue so the camera thread doesn’t hold mutex_dbse while performing potentially blocking I/O, rather than forcibly unlocking from another thread.
| pthread_mutex_unlock(&dbse->mutex_dbse); | |
| pthread_mutex_unlock(&cam_list[camindx]->stream.mutex); | |
| if ((cam_list[camindx]->camera_type == CAMERA_TYPE_NETCAM) && | |
| (cam_list[camindx]->netcam != nullptr)) { | |
| pthread_mutex_unlock(&cam_list[camindx]->netcam->mutex); | |
| pthread_mutex_unlock(&cam_list[camindx]->netcam->mutex_pktarray); | |
| pthread_mutex_unlock(&cam_list[camindx]->netcam->mutex_transfer); | |
| cam_list[camindx]->netcam->handler_stop = true; | |
| } | |
| if ((cam_list[camindx]->camera_type == CAMERA_TYPE_NETCAM) && | |
| (cam_list[camindx]->netcam_high != nullptr)) { | |
| pthread_mutex_unlock(&cam_list[camindx]->netcam_high->mutex); | |
| pthread_mutex_unlock(&cam_list[camindx]->netcam_high->mutex_pktarray); | |
| pthread_mutex_unlock(&cam_list[camindx]->netcam_high->mutex_transfer); | |
| /* Do not attempt to unlock other threads' mutexes here; that is undefined behavior. */ | |
| if ((cam_list[camindx]->camera_type == CAMERA_TYPE_NETCAM) && | |
| (cam_list[camindx]->netcam != nullptr)) { | |
| cam_list[camindx]->netcam->handler_stop = true; | |
| } | |
| if ((cam_list[camindx]->camera_type == CAMERA_TYPE_NETCAM) && | |
| (cam_list[camindx]->netcam_high != nullptr)) { |
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.
pthread_mutex_unlock(&mutex_camlst)has the same cross-thread/unlocked-mutex problem as above (undefined behavior with the defaultpthread_mutex_init(..., NULL)initialization). Additionally, the onlymutex_camlstusers appear to be camera add/delete and web request validation, so a hung camera handler thread cannot be holding this mutex; unlocking it here is unlikely to help but could corrupt other concurrent operations. Please remove this unlock from the watchdog path (or redesign the watchdog recovery so it doesn’t rely on unlocking mutexes it didn’t lock).