25
25
#include < lib/support/CodeUtils.h>
26
26
#include < lib/support/ScopedBuffer.h>
27
27
#include < lib/support/TestGroupData.h>
28
+ #include < platform/LockTracker.h>
28
29
29
30
#if CHIP_CONFIG_TRANSPORT_TRACE_ENABLED
30
31
#include " TraceDecoder.h"
@@ -222,17 +223,17 @@ CHIP_ERROR CHIPCommand::Run()
222
223
223
224
CHIP_ERROR err = StartWaiting (GetWaitDuration ());
224
225
225
- bool deferCleanup = (IsInteractive () && DeferInteractiveCleanup ());
226
-
227
- Shutdown ();
228
-
229
- if (deferCleanup)
226
+ if (IsInteractive ())
230
227
{
231
- sDeferredCleanups .insert (this );
228
+ bool timedOut;
229
+ // Give it 2 hours to run our cleanup; that should never get hit in practice.
230
+ CHIP_ERROR cleanupErr = RunOnMatterQueue (RunCommandCleanup, chip::System::Clock::Seconds16 (7200 ), &timedOut);
231
+ VerifyOrDie (cleanupErr == CHIP_NO_ERROR);
232
+ VerifyOrDie (!timedOut);
232
233
}
233
234
else
234
235
{
235
- Cleanup ();
236
+ CleanupAfterRun ();
236
237
}
237
238
238
239
MaybeTearDownStack ();
@@ -504,6 +505,56 @@ void CHIPCommand::RunQueuedCommand(intptr_t commandArg)
504
505
}
505
506
}
506
507
508
+ void CHIPCommand::RunCommandCleanup (intptr_t commandArg)
509
+ {
510
+ auto * command = reinterpret_cast <CHIPCommand *>(commandArg);
511
+ command->CleanupAfterRun ();
512
+ command->StopWaiting ();
513
+ }
514
+
515
+ void CHIPCommand::CleanupAfterRun ()
516
+ {
517
+ assertChipStackLockedByCurrentThread ();
518
+ bool deferCleanup = (IsInteractive () && DeferInteractiveCleanup ());
519
+
520
+ Shutdown ();
521
+
522
+ if (deferCleanup)
523
+ {
524
+ sDeferredCleanups .insert (this );
525
+ }
526
+ else
527
+ {
528
+ Cleanup ();
529
+ }
530
+ }
531
+
532
+ CHIP_ERROR CHIPCommand::RunOnMatterQueue (MatterWorkCallback callback, chip::System::Clock::Timeout timeout, bool * timedOut)
533
+ {
534
+ {
535
+ std::lock_guard<std::mutex> lk (cvWaitingForResponseMutex);
536
+ mWaitingForResponse = true ;
537
+ }
538
+
539
+ auto err = chip::DeviceLayer::PlatformMgr ().ScheduleWork (callback, reinterpret_cast <intptr_t >(this ));
540
+ if (CHIP_NO_ERROR != err)
541
+ {
542
+ {
543
+ std::lock_guard<std::mutex> lk (cvWaitingForResponseMutex);
544
+ mWaitingForResponse = false ;
545
+ }
546
+ return err;
547
+ }
548
+
549
+ auto waitingUntil = std::chrono::system_clock::now () + std::chrono::duration_cast<std::chrono::seconds>(timeout);
550
+ {
551
+ std::unique_lock<std::mutex> lk (cvWaitingForResponseMutex);
552
+ *timedOut = !cvWaitingForResponse.wait_until (lk, waitingUntil, [this ]() { return !this ->mWaitingForResponse ; });
553
+ }
554
+
555
+ return CHIP_NO_ERROR;
556
+ }
557
+
507
558
#if !CONFIG_USE_SEPARATE_EVENTLOOP
508
559
static void OnResponseTimeout (chip::System::Layer *, void * appState)
509
560
{
@@ -526,28 +577,15 @@ CHIP_ERROR CHIPCommand::StartWaiting(chip::System::Clock::Timeout duration)
526
577
}
527
578
else
528
579
{
529
- {
530
- std::lock_guard<std::mutex> lk (cvWaitingForResponseMutex);
531
- mWaitingForResponse = true ;
532
- }
533
-
534
- auto err = chip::DeviceLayer::PlatformMgr ().ScheduleWork (RunQueuedCommand, reinterpret_cast <intptr_t >(this ));
580
+ bool timedOut;
581
+ CHIP_ERROR err = RunOnMatterQueue (RunQueuedCommand, duration, &timedOut);
535
582
if (CHIP_NO_ERROR != err)
536
583
{
537
- {
538
- std::lock_guard<std::mutex> lk (cvWaitingForResponseMutex);
539
- mWaitingForResponse = false ;
540
- }
541
584
return err;
542
585
}
543
-
544
- auto waitingUntil = std::chrono::system_clock::now () + std::chrono::duration_cast<std::chrono::seconds>(duration);
586
+ if (timedOut)
545
587
{
546
- std::unique_lock<std::mutex> lk (cvWaitingForResponseMutex);
547
- if (!cvWaitingForResponse.wait_until (lk, waitingUntil, [this ]() { return !this ->mWaitingForResponse ; }))
548
- {
549
- mCommandExitStatus = CHIP_ERROR_TIMEOUT;
550
- }
588
+ mCommandExitStatus = CHIP_ERROR_TIMEOUT;
551
589
}
552
590
}
553
591
if (!IsInteractive ())
0 commit comments