private async Task WriteAll() { Buffer buffer; do { buffer = await writes.Dequeue(); log.LogInformation("Got buffer"); if (error == null) { try { if (buffer.offset < 0) { log.LogInformation("Got close buffer"); await CloseInternal(); } else { log.LogInformation("Got write buffer"); await WriteInternal(buffer); } } catch (Exception e) { log.LogError("Got exception writing stream " + e.ToString()); error = e.Message; errorType = ErrorType.IO; } } client.ReturnBuffer(buffer, errorType, error); } while (buffer.offset >= 0); log.LogInformation("Finished all writes"); }
private async Task DataLoop(bool errorState) { var managedBuffer = new byte[bufferSize]; var readData = new ReadData { eof = false, nRead = 0 }; while ((!readData.eof) || errorState) { log.LogInformation("Waiting for buffer"); var buffer = await queue.Dequeue(); if (buffer == null) { // we were interrupted, and have returned all the necessary buffers return; } if (errorState) { client.DiscardBuffer(buffer); } else { try { if (buffer.size != bufferSize) { throw new ApplicationException("Mismatched buffer sizes " + buffer.size + " != " + bufferSize); } if (buffer.offset == -1) { buffer.offset = offset; } else if (buffer.offset != offset) { throw new ApplicationException("Buffer offset " + buffer.offset + " expected " + offset); } log.LogInformation("Waiting for buffer read"); Task <ReadData> timeout = Task.Delay(SafetyTimeout).ContinueWith((t) => new ReadData()); Task <ReadData> reads = await Task.WhenAny(timeout, ReadBuffer(managedBuffer)); if (reads == timeout) { throw new ApplicationException("Excessive timeout on read operation"); } readData = reads.Result; log.LogInformation("Got buffer read " + readData.nRead); buffer.size = readData.nRead; Marshal.Copy(managedBuffer, 0, buffer.storage, readData.nRead); log.LogInformation("Returning to client"); client.ReceiveData(buffer, readData.eof); offset += (long)buffer.size; } catch (Exception e) { SendError(e, ErrorType.IO); client.DiscardBuffer(buffer); errorState = true; } } } }