@@ -231,10 +231,10 @@ Public Class LTFSWriter
231231 Set(value As Boolean)
232232 Dim previous = Interlocked.Exchange(_stopFlagValue, If(value, 1, 0))
233233 If value AndAlso previous = 0 Then
234- Dim fastProviderSnapshot = Volatile.Read(_activeFastReaderProvider )
235- If fastProviderSnapshot IsNot Nothing Then
234+ Dim writerCancellationSnapshot = Volatile.Read(_activeWriterCancellation )
235+ If writerCancellationSnapshot IsNot Nothing Then
236236 Try
237- fastProviderSnapshot .Cancel()
237+ writerCancellationSnapshot .Cancel()
238238 Catch
239239 End Try
240240 End If
@@ -6890,6 +6890,7 @@ Public Class LTFSWriter
68906890 Private _PipeBufferLength As Long = 0
68916891 Private _stopFlagValue As Integer = 0
68926892 Private _activeFastReaderProvider As IFastReaderConsumer = Nothing
6893+ Private _activeWriterCancellation As CancellationTokenSource = Nothing
68936894 Private _directCopySourceOffer As DirectTapeCopySourceOffer = Nothing
68946895 Private _directCopyTargetSession As DirectTapeCopyTargetSession = Nothing
68956896 Private _directCopyManifest As DirectTapeCopyManifest = Nothing
@@ -7625,7 +7626,13 @@ Public Class LTFSWriter
76257626 End If
76267627
76277628 PipePause = True
7628- Dim waitCancellation As New CancellationTokenSource()
7629+ Dim writerCancellationSnapshot = Threading.Volatile.Read(_activeWriterCancellation)
7630+ Dim waitCancellation As CancellationTokenSource
7631+ If writerCancellationSnapshot Is Nothing Then
7632+ waitCancellation = New CancellationTokenSource()
7633+ Else
7634+ waitCancellation = CancellationTokenSource.CreateLinkedTokenSource(writerCancellationSnapshot.Token)
7635+ End If
76297636 Dim previousWaitCancellation = Threading.Interlocked.Exchange(_fastReaderWaitCancellation, waitCancellation)
76307637 If previousWaitCancellation IsNot Nothing Then
76317638 Try
@@ -7746,7 +7753,8 @@ Public Class LTFSWriter
77467753 driveHandle As IntPtr,
77477754 p As TapeUtils.PositionData,
77487755 Optional expectedDedupeHash As String = "",
7749- Optional tarScanner As TarMetadataScanner = Nothing) As Boolean
7756+ Optional tarScanner As TarMetadataScanner = Nothing,
7757+ Optional cancellationToken As CancellationToken = Nothing) As Boolean
77507758 Dim remainingInFile As Long = fr.File.length
77517759 Dim eofSeen As Boolean = False
77527760 Dim writeCallCount As Long = 0
@@ -7800,7 +7808,7 @@ Public Class LTFSWriter
78007808 While Not StopFlag AndAlso remainingInFile > 0
78017809 WaitForFastReaderRefill(fastProvider)
78027810
7803- Dim slot As RustFastReaderProvider.Slot = fastProvider.ReadSlot(fileIndex, Threading.CancellationToken.None )
7811+ Dim slot As RustFastReaderProvider.Slot = fastProvider.ReadSlot(fileIndex, cancellationToken )
78047812 Dim expectedOffset = fr.File.length - remainingInFile
78057813 If slot.FileIndex <> fileIndex OrElse slot.FileOffset <> expectedOffset Then
78067814 fastProvider.AdvanceSlot(slot)
@@ -8068,7 +8076,7 @@ Public Class LTFSWriter
80688076 End Using
80698077 End Using
80708078 End Using
8071- Dim eofSlot = fastProvider.ReadSlot(fileIndex, Threading.CancellationToken.None )
8079+ Dim eofSlot = fastProvider.ReadSlot(fileIndex, cancellationToken )
80728080 Dim validEof = eofSlot.FileIndex = fileIndex AndAlso
80738081 eofSlot.FileOffset = fr.File.length AndAlso
80748082 eofSlot.Length = 0 AndAlso
@@ -8136,6 +8144,7 @@ Public Class LTFSWriter
81368144 Dim th As New Threading.Thread(
81378145 Sub()
81388146 Dim OnWriteFinishMessage As String = ""
8147+ Dim writerCancellation As CancellationTokenSource = Nothing
81398148 Dim provider As FileDataProvider = Nothing
81408149 Dim fastProvider As IFastReaderConsumer = Nothing
81418150 Dim diskFastProvider As RustFastReaderProvider = Nothing
@@ -8153,6 +8162,9 @@ Public Class LTFSWriter
81538162 Dim directManifest As DirectTapeCopyManifest = Nothing
81548163 Dim isDirectCopy As Boolean = False
81558164 Try
8165+ writerCancellation = New CancellationTokenSource()
8166+ Threading.Interlocked.Exchange(_activeWriterCancellation, writerCancellation)
8167+ If StopFlag Then writerCancellation.Cancel()
81568168 ClearWriteCompletionState()
81578169 PipeBufferLength = 0
81588170 SetStatusLight(LWStatus.Busy)
@@ -8516,7 +8528,7 @@ Public Class LTFSWriter
85168528 TotalBytesUnindexed += fr.File.length
85178529 ElseIf useFastReader AndAlso Not IsIndexPartition Then
85188530 Dim providerFileIndex = If(fr.IsDirectTapeCopy, CInt(fr.DirectCopyOrdinal), i)
8519- If Not WriteFileFromFastReader(fastProvider, providerFileIndex, fr, driveHandle, p, currentPlan.ExpectedDedupeHash, tarScanner) Then Exit For
8531+ If Not WriteFileFromFastReader(fastProvider, providerFileIndex, fr, driveHandle, p, currentPlan.ExpectedDedupeHash, tarScanner, writerCancellation.Token ) Then Exit For
85208532 ElseIf (fr.File.length <= plabel.blocksize) AndAlso (fr.FileOffset = 0) AndAlso (fr.File.length = fr.SegmentLength) Then
85218533 Dim succ As Boolean = False
85228534 Dim FileData(CInt(fr.File.length - 1)) As Byte
@@ -9273,7 +9285,6 @@ Public Class LTFSWriter
92739285 End If
92749286 End Try
92759287 End If
9276- ResetFastReaderBufferWait()
92779288 Try
92789289 If provider IsNot Nothing Then
92799290 provider.Cancel()
@@ -9340,6 +9351,19 @@ Public Class LTFSWriter
93409351 Log.Error(cleanupEx, "Power policy restore failed during writer cleanup.")
93419352 End Try
93429353 End If
9354+ If writerCancellation IsNot Nothing Then
9355+ Try
9356+ If ReferenceEquals(Threading.Volatile.Read(_activeWriterCancellation), writerCancellation) Then
9357+ Threading.Interlocked.CompareExchange(_activeWriterCancellation, Nothing, writerCancellation)
9358+ End If
9359+ writerCancellation.Dispose()
9360+ Catch cleanupEx As Exception
9361+ Log.Error(cleanupEx, "Writer cancellation cleanup failed.")
9362+ Finally
9363+ writerCancellation = Nothing
9364+ End Try
9365+ End If
9366+ ResetFastReaderBufferWait()
93439367 Try
93449368 LockGUI(False)
93459369 Catch cleanupEx As Exception
0 commit comments