Skip to content

Commit fe9fac3

Browse files
committed
fix: crash when cancel
1 parent 171930f commit fe9fac3

1 file changed

Lines changed: 33 additions & 9 deletions

File tree

‎LTFSCopyGUI/Forms/LTFSWriter.vb‎

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)