private void _PerpetualWriterMethod(object state)
{
TraceOutput(TraceBits.WriterThread, "_PerpetualWriterMethod START");
try
{
do
{
// wait for the next session
TraceOutput(TraceBits.Synch | TraceBits.WriterThread, "Synch _sessionReset.WaitOne(begin) PWM");
_sessionReset.WaitOne();
TraceOutput(TraceBits.Synch | TraceBits.WriterThread, "Synch _sessionReset.WaitOne(done) PWM");
if (_isDisposed) break;
TraceOutput(TraceBits.Synch | TraceBits.WriterThread, "Synch _sessionReset.Reset() PWM");
_sessionReset.Reset();
// repeatedly write buffers as they become ready
WorkItem workitem = null;
Ionic.Zlib.CRC32 c= new Ionic.Zlib.CRC32();
do
{
workitem = _pool[_nextToWrite % _pc];
lock(workitem)
{
if (_noMoreInputForThisSegment)
TraceOutput(TraceBits.Write,
"Write drain wi({0}) stat({1}) canuse({2}) cba({3})",
workitem.index,
workitem.status,
(workitem.status == (int)WorkItem.Status.Compressed),
workitem.compressedBytesAvailable);
do
{
if (workitem.status == (int)WorkItem.Status.Compressed)
{
TraceOutput(TraceBits.WriteBegin,
"Write begin wi({0}) stat({1}) cba({2})",
workitem.index,
workitem.status,
workitem.compressedBytesAvailable);
workitem.status = (int)WorkItem.Status.Writing;
_outStream.Write(workitem.compressed, 0, workitem.compressedBytesAvailable);
c.Combine(workitem.crc, workitem.inputBytesAvailable);
_totalBytesProcessed += workitem.inputBytesAvailable;
_nextToWrite++;
workitem.inputBytesAvailable= 0;
workitem.status = (int)WorkItem.Status.Done;
TraceOutput(TraceBits.WriteDone,
"Write done wi({0}) stat({1}) cba({2})",
workitem.index,
workitem.status,
workitem.compressedBytesAvailable);
Monitor.Pulse(workitem);
break;
}
else
{
int wcycles = 0;
// I've locked a workitem I cannot use.
// Therefore, wake someone else up, and then release the lock.
while (workitem.status != (int)WorkItem.Status.Compressed)
{
TraceOutput(TraceBits.WriteWait,
"Write waiting wi({0}) stat({1}) nw({2}) nf({3}) nomore({4})",
workitem.index,
workitem.status,
_nextToWrite, _nextToFill,
_noMoreInputForThisSegment );
if (_noMoreInputForThisSegment && _nextToWrite == _nextToFill)
break;
wcycles++;
// wake up someone else
Monitor.Pulse(workitem);
// release and wait
Monitor.Wait(workitem);
if (workitem.status == (int)WorkItem.Status.Compressed)
TraceOutput(TraceBits.WriteWait,
"Write A-OK wi({0}) stat({1}) iba({2}) cba({3}) cyc({4})",
workitem.index,
workitem.status,
workitem.inputBytesAvailable,
workitem.compressedBytesAvailable,
wcycles);
}
if (_noMoreInputForThisSegment && _nextToWrite == _nextToFill)
break;
}
}
while (true);
}
if (_noMoreInputForThisSegment)
TraceOutput(TraceBits.Write,
"Write nomore nw({0}) nf({1}) break({2})",
_nextToWrite, _nextToFill, (_nextToWrite == _nextToFill));
if (_noMoreInputForThisSegment && _nextToWrite == _nextToFill)
break;
} while (true);
// Finish:
// After writing a series of buffers, closing each one with
// Flush.Sync, we now write the final one as Flush.Finish, and
// then stop.
byte[] buffer = new byte[128];
ZlibCodec compressor = new ZlibCodec();
int rc = compressor.InitializeDeflate(_compressLevel, false);
compressor.InputBuffer = null;
compressor.NextIn = 0;
compressor.AvailableBytesIn = 0;
compressor.OutputBuffer = buffer;
compressor.NextOut = 0;
compressor.AvailableBytesOut = buffer.Length;
rc = compressor.Deflate(FlushType.Finish);
if (rc != ZlibConstants.Z_STREAM_END && rc != ZlibConstants.Z_OK)
throw new Exception("deflating: " + compressor.Message);
if (buffer.Length - compressor.AvailableBytesOut > 0)
{
TraceOutput(TraceBits.WriteBegin,
"Write begin flush bytes({0})",
buffer.Length - compressor.AvailableBytesOut);
_outStream.Write(buffer, 0, buffer.Length - compressor.AvailableBytesOut);
TraceOutput(TraceBits.WriteBegin,
"Write done flush");
}
compressor.EndDeflate();
_Crc32 = c.Crc32Result;
// signal that writing is complete:
TraceOutput(TraceBits.Synch, "Synch _writingDone.Set() PWM");
_writingDone.Set();
}
while (true);
}
catch (System.Exception exc1)
{
lock(_eLock)
{
// expose the exception to the main thread
if (_pendingException!=null)
_pendingException = exc1;
}
}
TraceOutput(TraceBits.WriterThread, "_PerpetualWriterMethod FINIS");
}
#endif