@@ -368,6 +368,25 @@ class TRealBlockDevice : public IBlockDevice {
368368 }
369369 }
370370
371+ void ExecuteOrScheduleCompletion (TCompletionAction *action) {
372+ if (action->ShouldBeExecutedInCompletionThread ) {
373+ Device.CompletionThread ->Schedule (action);
374+ } else {
375+ if (action->CanHandleResult ()) {
376+ action->Exec (Device.PCtx ->ActorSystem );
377+ } else {
378+ TString errorReason = action->ErrorReason ;
379+
380+ action->Release (Device.PCtx ->ActorSystem );
381+
382+ if (!Device.QuitCounter .IsBlocked ()) {
383+ Device.BecomeErrorState (TStringBuilder ()
384+ << " CompletionAction error, operation info# " << errorReason);
385+ }
386+ }
387+ }
388+ }
389+
371390 void Exec (TAsyncIoOperationResult *event) {
372391 IAsyncIoOperation *op = event->Operation ;
373392 // Add up the execution time of all the events
@@ -425,7 +444,7 @@ class TRealBlockDevice : public IBlockDevice {
425444 WaitingNoops[idx % MaxWaitingNoops] = completionAction->FlushAction ;
426445 completionAction->FlushAction = nullptr ;
427446 }
428- Device. CompletionThread -> Schedule (completionAction);
447+ ExecuteOrScheduleCompletion (completionAction);
429448 auto seqnoL6 = AtomicGetAndIncrement (Device.Mon .SeqnoL6 );
430449 Device.Mon .L6 .Set (duration > Device.Reordering , seqnoL6);
431450 }
@@ -443,7 +462,7 @@ class TRealBlockDevice : public IBlockDevice {
443462 LWTRACK (PDiskDeviceGetFromWaiting, WaitingNoops[i]->Orbit );
444463 double durationMs = HPMilliSecondsFloat (HPNow () - WaitingNoops[i]->GetTime );
445464 Device.Mon .DeviceFlushDuration .Increment (durationMs);
446- Device. CompletionThread -> Schedule (WaitingNoops[i]);
465+ ExecuteOrScheduleCompletion (WaitingNoops[i]);
447466 WaitingNoops[i] = nullptr ;
448467 }
449468 ++NextPossibleNoop;
0 commit comments