Skip to content

Added fix for hangs - #38

Merged
matt2005 merged 4 commits into
mainfrom
develop
Nov 13, 2025
Merged

Added fix for hangs#38
matt2005 merged 4 commits into
mainfrom
develop

Conversation

@matt2005

Copy link
Copy Markdown
Member

No description provided.

Problem:
During AndroidAutoEntity teardown, services would receive channel errors when
messenger/transport stopped. Each error triggered onChannelError() which could
call triggerQuit() again, causing re-entrant shutdown attempts and application
state corruption leading to freezes.

Solution:
- Added std::atomic<bool> stopping_ flag to AndroidAutoEntity
- Set stopping_=true at start of stop() before dispatching shutdown work
- onChannelError() now:
  1. Returns early for OPERATION_ABORTED (expected from messenger->stop())
  2. Returns early if stopping_=true (prevents re-entrant quit)
  3. Otherwise logs fatal error and triggers quit normally

Impact:
- Prevents cascading error-triggered quits during teardown
- Shutdown is now single-pass and deterministic
- Works with updated aasdk Messenger that rejects promises on stop
- OPERATION_ABORTED errors during stop are expected and logged at debug level

Depends on: aasdk commit 3365b08 (Messenger::stop() promise rejection)
Problem:
SensorService::sensorPolling() could be dispatched to strand before stop() executed,
leading to a race where:
1. Timer callback queued on strand
2. stop() sets stopPolling=true and cancels timer
3. Already-queued callback runs, ignores stopPolling, and reschedules timer
4. Polling continues indefinitely after stop, blocking clean shutdown

Solution:
- stop(): Added timer_.cancel() to immediately abort pending timer callbacks
- sensorPolling(): Added second stopPolling check inside dispatched handler
- sensorPolling(): Added third stopPolling check before rescheduling timer
- onChannelError(): Treat OPERATION_ABORTED as debug-level (expected during stop)

Impact:
- Timer polling stops reliably even if callback was queued before stop()
- No more 'sensorPolling()' logs after 'stop()' completes
- Clean shutdown without lingering async operations
- Reduces spurious error logs during normal shutdown

Race window eliminated: callback now aborts before work or rescheduling.
Problem:
1. stopPlayback signal used Qt::QueuedConnection but onStopPlayback() could still
   block if mediaPlayer_->stop() waited on GStreamer pipeline teardown
2. write() could be called after stop() cleared playerReady_, writing to a stopped
   buffer and potentially causing Qt event loop hangs
3. Widget hide/focus operations were interleaved with player stop, extending lock time

Solution:
- write(): Added early return if !playerReady_ to prevent writes after stop
- onStopPlayback(): Reordered to stop player first, then hide widget (reduce lock time)
- onStopPlayback(): Added null checks for mediaPlayer_ and videoWidget_ safety
- onStopPlayback(): Added completion log for shutdown tracing
- Constructor: Added comment clarifying QueuedConnection prevents deadlock

Impact:
- Video output stops cleanly without blocking Qt main thread
- No writes attempted after playerReady_ cleared
- Reduced mutex hold time during teardown
- UI clock keeps ticking during AA exit (no freeze)
- Clean logs show 'onStopPlayback() complete' marker

Note: stopPlayback already used QueuedConnection; added explanatory comment.
Problem:
All service onChannelError() handlers logged every error at ERROR level, including
OPERATION_ABORTED errors that are now intentionally sent by aasdk Messenger::stop()
during clean shutdown. This created noisy error logs during normal AA exit.

Solution:
Updated onChannelError() in all services to check error code:
- OPERATION_ABORTED -> log at DEBUG level with '(expected during stop)' note
- All other errors -> log at ERROR level as before

Services updated:
- AudioMediaSinkService (3 channels: MEDIA_AUDIO, GUIDANCE_AUDIO, SYSTEM_AUDIO)
- VideoMediaSinkService (MEDIA_SINK_VIDEO)
- InputSourceService
- SensorService (already done in timer race fix commit)
- AndroidAutoEntity (already done in stopping_ guard commit)

Impact:
- Clean shutdown logs at DEBUG: no error noise during normal AA exit
- Real errors still logged at ERROR for troubleshooting
- Works with updated aasdk Messenger that rejects promises with OPERATION_ABORTED
- Reduced log spam from ~7 ERROR lines to 0 during shutdown

Depends on: aasdk commit 3365b08 (Messenger::stop() promise rejection)
@matt2005
matt2005 merged commit 68f2d4f into main Nov 13, 2025
2 of 10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant