fix(compresssave): wait for async worker before closing save

This commit is contained in:
2026-08-05 03:30:38 +08:00
parent 732aceae4e
commit 009773f06b
5 changed files with 421 additions and 20 deletions
+4 -2
View File
@@ -20,6 +20,7 @@ public unsafe class BufferWriter : BinaryWriter
private long SuplusCapacity => _endPos - _curPos;
private long _swapedBytes;
private bool _closed;
public long WriteSum => _swapedBytes + _curPos - _startPos;
@@ -91,8 +92,9 @@ public unsafe class BufferWriter : BinaryWriter
protected override void Dispose(bool disposing)
{
if (disposing)
if (disposing && !_closed)
{
_closed = true;
SwapBuffer();
}
base.Dispose(disposing);
@@ -288,4 +290,4 @@ public unsafe class BufferWriter : BinaryWriter
}
Write((byte)num);
}
}
}
+32 -17
View File
@@ -34,7 +34,8 @@ public class CompressionStream : Stream
private IntPtr _cctx;
private long _lastError;
private bool _stopWorker = true;
private volatile bool _stopWorker = true;
private Thread _compressThread;
public bool HasError()
{
@@ -90,8 +91,8 @@ public class CompressionStream : Stream
_useMultiThread = multiThread;
if (!multiThread) return;
_stopWorker = false;
var compressThread = new Thread(CompressAsync);
compressThread.Start();
_compressThread = new Thread(CompressAsync);
_compressThread.Start();
}
private void InitBuffer(byte[] readBuffer, byte[] writeBuffer, byte[] outputBuffer)
@@ -105,9 +106,7 @@ public class CompressionStream : Stream
{
_doubleBuffer.SwapBuffer();
if (_useMultiThread)
{
_doubleBuffer.WaitReadEnd();
}
lock (_outBuffer)
{
OutStream.Flush();
@@ -151,7 +150,7 @@ public class CompressionStream : Stream
private void CompressAsync()
{
while (!_stopWorker)
while (!_stopWorker || _doubleBuffer.HasPendingBuffer)
{
Compress_Internal();
}
@@ -198,26 +197,42 @@ public class CompressionStream : Stream
public override void Close()
{
if (_closed) return;
BufferWriter.Close();
_closed = true;
//Console.WriteLine($"FLUSH");
Flush();
// try stop the worker
_stopWorker = true;
_doubleBuffer.SwapBuffer();
try
{
BufferWriter.Close();
_closed = true;
Flush();
}
finally
{
StopWorker();
}
var size = _wrapper.CompressEnd(_cctx, _outBuffer, _outBuffer.Length);
//Debug.Log($"End");
OutStream.Write(_outBuffer, 0, (int)size);
base.Close();
}
private void StopWorker()
{
if (!_useMultiThread || _compressThread == null) return;
_stopWorker = true;
try
{
if (!_doubleBuffer.HasPendingBuffer)
_doubleBuffer.SwapBuffer();
}
finally
{
_compressThread.Join();
_compressThread = null;
}
}
protected override void Dispose(bool disposing)
{
FreeContext();
base.Dispose(disposing);
}
}
}
+3 -1
View File
@@ -68,6 +68,8 @@ public class DoubleBuffer(byte[] readingBuffer, byte[] writingBuffer, Action onR
private readonly Semaphore _readEnd = new(1, 1);
private readonly Semaphore _writeEnd = new(0, 1);
public bool HasPendingBuffer => _readBuffer != null;
public ByteSpan ReadBegin()
{
_writeEnd.WaitOne();
@@ -112,4 +114,4 @@ public class DoubleBuffer(byte[] readingBuffer, byte[] writingBuffer, Action onR
{
_writeEnd.Release();
}
}
}