@@ -25,9 +25,16 @@ namespace ControllerCommands {
2525 }
2626
2727 if (!m_workMem) {
28- m_workMem = (u8 *)aligned_alloc (0x1000 , m_workMem_size);
29- if (!m_workMem) {
30- Logger::instance ().log (" Failed to initialize virtual controller." , " initController() aligned_alloc() failed." );
28+ try {
29+ m_workMem = (u8 *)aligned_alloc (0x1000 , m_workMem_size);
30+ if (!m_workMem) {
31+ Logger::instance ().log (" Failed to initialize virtual controller." , " initController() aligned_alloc() failed." );
32+ hiddbgExit ();
33+ return ;
34+ }
35+ } catch (...) {
36+ Logger::instance ().log (" Exception during m_workMem allocation." );
37+ hiddbgExit ();
3138 return ;
3239 }
3340 }
@@ -225,14 +232,30 @@ namespace ControllerCommands {
225232 * @param Condition variable for the sender queue.
226233 * @param Atomic boolean for error handling, passed from the command thread.
227234 */
228- void Controller::startControllerThread (LockFreeQueue<std::vector<char >>& senderQueue, std::condition_variable& senderCv, std::atomic_bool& error) {
235+ void Controller::startControllerThread (LockFreeQueue<std::vector<char >>& senderQueue, std::condition_variable& senderCv, std::atomic_bool& stop, std::atomic_bool& error) {
229236 if (m_ccThreadRunning) {
230237 Logger::instance ().log (" Controller thread already running." );
231238 return ;
232239 }
233240
234241 Logger::instance ().log (" Starting commandLoopPA thread." );
235- m_ccThread = std::thread (&Controller::commandLoopPA, this , std::ref (senderQueue), std::ref (senderCv), std::ref (error));
242+ try {
243+ m_ccThread = std::thread (&Controller::commandLoopPA, this , std::ref (senderQueue), std::ref (senderCv), std::ref (stop), std::ref (error));
244+ m_ccThreadRunning = true ;
245+ Logger::instance ().log (" commandLoopPA thread created successfully." );
246+ } catch (const std::exception& e) {
247+ Logger::instance ().log (" Failed to create commandLoopPA thread: " , e.what ());
248+ m_ccThreadRunning = false ;
249+ stop = true ;
250+ error = true ;
251+ throw ;
252+ } catch (...) {
253+ Logger::instance ().log (" Unknown exception creating commandLoopPA thread." );
254+ m_ccThreadRunning = false ;
255+ stop = true ;
256+ error = true ;
257+ throw ;
258+ }
236259 }
237260
238261 /* *
@@ -241,14 +264,13 @@ namespace ControllerCommands {
241264 * @param Condition variable for the sender queue.
242265 * @param Atomic boolean for error handling, passed from the command thread.
243266 */
244- void Controller::commandLoopPA (LockFreeQueue<std::vector<char >>& senderQueue, std::condition_variable& senderCv, std::atomic_bool& error) {
267+ void Controller::commandLoopPA (LockFreeQueue<std::vector<char >>& senderQueue, std::condition_variable& senderCv, std::atomic_bool& stop, std::atomic_bool& error) {
245268 const std::chrono::microseconds earlyWake (1000 );
246269 m_nextStateChange = WallClock::max ();
247- m_ccThreadRunning = true ;
248270 Logger::instance ().log (" commandLoopPA() started." );
249271
250272 std::unique_lock<std::mutex> lock (m_ccMutex);
251- while (!error ) {
273+ while (!stop ) {
252274 WallClock now = std::chrono::steady_clock::now ();
253275 ControllerCommand cmd;
254276 if (now >= m_nextStateChange) {
@@ -270,17 +292,29 @@ namespace ControllerCommands {
270292 if (m_ccCurrentCommand.seqnum != 0 ){
271293 Logger::instance ().log (" cqSendState() command finished with seqnum: " + std::to_string (m_ccCurrentCommand.seqnum ));
272294 std::string res = " cqCommandFinished " + std::to_string (m_ccCurrentCommand.seqnum ) + " \r\n " ;
273- senderQueue.push (std::vector<char >(res.begin (), res.end ()));
274- senderCv.notify_one ();
295+ if (!senderQueue.full ()) {
296+ senderQueue.push (std::vector<char >(res.begin (), res.end ()));
297+ senderCv.notify_one ();
298+ } else {
299+ Logger::instance ().log (" Sender queue full, dropping command finished message." );
300+ }
275301 }
276302
277303 m_ccCurrentCommand = cmd;
278- m_ccCv.wait_until (lock, m_nextStateChange - earlyWake, [&] { return error || now + earlyWake >= m_nextStateChange; });
304+ m_ccCv.wait_until (lock, m_nextStateChange - earlyWake, [&] { return stop || error || now + earlyWake >= m_nextStateChange; });
305+ if (error) {
306+ m_ccQueue.clear ();
307+ cqControllerState (ControllerCommand{});
308+ m_nextStateChange = WallClock::max ();
309+ }
279310 }
280311
281312 m_ccQueue.clear ();
282313 cqControllerState (ControllerCommand{});
283314 detachController ();
315+ m_ccThreadRunning = false ;
316+ m_isEnabledPA = false ;
317+ stop = true ;
284318 Logger::instance ().log (" commandLoopPA() exiting thread..." );
285319 }
286320
@@ -290,7 +324,15 @@ namespace ControllerCommands {
290324 */
291325 void Controller::cqControllerState (const ControllerCommand& cmd) {
292326 Logger::instance ().log (" cqControllerState() called with seqnum: " + std::to_string (cmd.seqnum ));
293- initController ();
327+ try {
328+ initController ();
329+ } catch (const std::exception& e) {
330+ Logger::instance ().log (" cqControllerState() initController() failed: " , e.what ());
331+ return ;
332+ } catch (...) {
333+ Logger::instance ().log (" cqControllerState() initController() unknown exception." );
334+ return ;
335+ }
294336
295337 m_hiddbgHdlsState.buttons = cmd.state .buttons ;
296338 m_hiddbgHdlsState.analog_stick_l .x = cmd.state .left_joystick_x ;
@@ -362,11 +404,8 @@ namespace ControllerCommands {
362404 * @brief Join the PA controller thread if it is running.
363405 */
364406 void Controller::cqJoinThread () {
365- if (m_ccThreadRunning && m_ccThread.joinable ()) {
366- m_ccThread.join ();
367- m_ccThreadRunning = false ;
368- Logger::instance ().log (" commandLoopPA thread finished." );
369- }
407+ m_ccCv.notify_all ();
408+ if (m_ccThread.joinable ()) m_ccThread.join ();
370409 }
371410
372411 /* *
0 commit comments