From 0c1de666fa29cfdcf8215c9aba8ed42ae5518f01 Mon Sep 17 00:00:00 2001 From: Christian Hammacher Date: Fri, 18 Oct 2024 10:53:39 +0200 Subject: [PATCH] Changes to fix M99 (WIP) --- .../SPI/Channel/Processor.cs | 72 ++++++++----------- src/DuetControlServer/SPI/Interface.cs | 4 +- 2 files changed, 33 insertions(+), 43 deletions(-) diff --git a/src/DuetControlServer/SPI/Channel/Processor.cs b/src/DuetControlServer/SPI/Channel/Processor.cs index b5ae44499..03d67b837 100644 --- a/src/DuetControlServer/SPI/Channel/Processor.cs +++ b/src/DuetControlServer/SPI/Channel/Processor.cs @@ -121,7 +121,6 @@ public State Push(CodeFile? file = null) } // Done - CurrentState.SetBusy(true); Stack.Push(state); CurrentState = state; return state; @@ -526,14 +525,19 @@ public async Task SetMacroPausable(bool isPausable) } /// - /// Called when the last or all files have been aborted + /// Called when the last or all files have been aborted by the firmware /// /// Whether to abort all files - /// Whether the request came from the firmware - public void FilesAborted(bool abortAll, bool fromFirmware) + public void FilesAborted(bool abortAll) { bool macroAborted = false; + // If only the last macro is aborted, we may have a pending reply for e.g. M99 + if (!abortAll) + { + ResolvePendingReplies(); + } + // Clean up the stack Code? startCode = null; while (CurrentState.WaitingForAcknowledgement || CurrentState.File is MacroFile) @@ -548,9 +552,9 @@ public void FilesAborted(bool abortAll, bool fromFirmware) { using (macro.Lock()) { - // Resolve potential start codes when the macro file finishes - if (startCode is not null) + if (startCode is not null && abortAll) { + // Wait for the macro to be fully cancelled and then cancel the code that started it _ = macro.WaitForFinishAsync().ContinueWith(async task => { try @@ -571,14 +575,14 @@ public void FilesAborted(bool abortAll, bool fromFirmware) } else if (startCode is not null) { - // Cancel the code that started the blocking message prompt + // This is a message prompt. Cancel the code that started it Codes.Processor.CancelCode(startCode); startCode = null; } // Pop the stack Pop(); - if (startCode is not null) + if (startCode is not null && abortAll) { _logger.Debug("==> Unfinished starting code: {0}", startCode); } @@ -593,7 +597,6 @@ public void FilesAborted(bool abortAll, bool fromFirmware) if (abortAll) { // Cancel pending codes and requests - _allFilesAborted = !fromFirmware && (DataTransfer.ProtocolVersion >= 3); InvalidateRegular(); } else @@ -601,14 +604,25 @@ public void FilesAborted(bool abortAll, bool fromFirmware) // Invalidate remaining buffered codes from the last macro file foreach (Code bufferedCode in BufferedCodes) { - Codes.Processor.CancelCode(bufferedCode); + if (bufferedCode != startCode) + { + Codes.Processor.CancelCode(bufferedCode); + } } BufferedCodes.Clear(); BytesBuffered = 0; + + // If only the last file was closed (e.g. from M99), carry on with the execution of the code that started it + if (startCode is not null) + { + BytesBuffered += startCode.BinarySize; + BufferedCodes.Insert(0, startCode); + _logger.Debug("==> Resuming unfinished starting code: {0}", startCode); + } } // Abort the file print if necessary - if ((Channel == CodeChannel.File || Channel == CodeChannel.File2) && (abortAll || !macroAborted)) + if ((Channel is CodeChannel.File or CodeChannel.File2) && (abortAll || !macroAborted)) { using (JobProcessor.Lock()) { @@ -618,15 +632,11 @@ public void FilesAborted(bool abortAll, bool fromFirmware) } /// - /// Abort the last or all files asynchronously + /// Abort all files asynchronously /// - /// Whether to abort all files - /// Whether the request came from the firmware /// Asynchronous task - public async Task AbortFilesAsync(bool abortAll, bool fromFirmware) + public async Task AbortAllFilesAsync() { - bool macroAborted = false; - // Clean up the stack Code? startCode = null; while (CurrentState.WaitingForAcknowledgement || CurrentState.File is MacroFile) @@ -660,7 +670,6 @@ public async Task AbortFilesAsync(bool abortAll, bool fromFirmware) // Abort the macro file macro.Abort(); } - macroAborted = true; } else if (startCode is not null) { @@ -675,33 +684,14 @@ public async Task AbortFilesAsync(bool abortAll, bool fromFirmware) { _logger.Debug("==> Unfinished starting code: {0}", startCode); } - - // Stop if only a single file is supposed to be aborted - if (!abortAll && macroAborted) - { - break; - } } - if (abortAll) - { - // Cancel pending codes and requests - _allFilesAborted = !fromFirmware && (DataTransfer.ProtocolVersion >= 3); - InvalidateRegular(); - } - else - { - // Invalidate remaining buffered codes from the last macro file - foreach (Code bufferedCode in BufferedCodes) - { - Codes.Processor.CancelCode(bufferedCode); - } - BufferedCodes.Clear(); - BytesBuffered = 0; - } + // Cancel pending codes and requests + _allFilesAborted = (DataTransfer.ProtocolVersion >= 3); + InvalidateRegular(); // Abort the job files if necessary - if ((Channel == CodeChannel.File || Channel == CodeChannel.File2) && (abortAll || !macroAborted)) + if (Channel is CodeChannel.File or CodeChannel.File2) { using (await JobProcessor.LockAsync()) { diff --git a/src/DuetControlServer/SPI/Interface.cs b/src/DuetControlServer/SPI/Interface.cs index b4d04d1d8..0f9712ac7 100644 --- a/src/DuetControlServer/SPI/Interface.cs +++ b/src/DuetControlServer/SPI/Interface.cs @@ -689,7 +689,7 @@ public static async Task AbortAllAsync(CodeChannel channel) using (await _channels[channel].LockAsync()) { - await _channels[channel].AbortFilesAsync(true, false); + await _channels[channel].AbortAllFilesAsync(); } } @@ -1188,7 +1188,7 @@ private static void HandleAbortFileRequest() using (_channels[channel].Lock()) { - _channels[channel].FilesAborted(abortAll, true); + _channels[channel].FilesAborted(abortAll); } }