/// <summary> /// Private dispose method to release managed/unmanaged objects. /// If disposing = true clean up managed resources as well as unmanaged resources. /// If disposing = false only clean up unmanaged resources. /// </summary> /// <param name="disposing">Indicates whether or not to dispose managed resources.</param> protected override void Dispose(bool disposing) { if (disposing) { if (null != this.MemoryStream) { this.MemoryStream.Dispose(); this.MemoryStream = null; } if (null != this.MemoryBuffer) { this.MemoryManager.ReleaseBuffer(this.MemoryBuffer); this.MemoryManager = null; } } }
public TransferDownloadStream( MemoryManager memoryManager, TransferDownloadBuffer firstBuffer, int firstOffset, int firstCount, TransferDownloadBuffer secondBuffer, int secondOffset, int secondCount) { this.memoryManager = memoryManager; this.firstBuffer = firstBuffer; this.firstOffset = firstOffset; this.firstStream = new MemoryStream(this.firstBuffer.MemoryBuffer, firstOffset, firstCount); if (null != secondBuffer) { this.secondBuffer = secondBuffer; this.secondOffset = secondOffset; this.secondStream = new MemoryStream(this.secondBuffer.MemoryBuffer, secondOffset, secondCount); } }
/// <summary> /// Initializes a new instance of the /// <see cref="TransferScheduler" /> class. /// </summary> /// <param name="options">BlobTransfer options.</param> public TransferScheduler(TransferConfigurations options) { // If no options specified create a default one. this.transferOptions = options ?? new TransferConfigurations(); this.internalControllerQueue = new ConcurrentQueue<ITransferController>(); this.controllerQueue = new BlockingCollection<ITransferController>( this.internalControllerQueue); this.memoryManager = new MemoryManager( this.transferOptions.MaximumCacheSize, this.transferOptions.BlockSize); this.randomGenerator = new Random(); this.scheduleSemaphore = new SemaphoreSlim( this.transferOptions.ParallelOperations, this.transferOptions.ParallelOperations); this.StartSchedule(); }
/// <summary> /// Private dispose method to release managed/unmanaged objects. /// If disposing is true clean up managed resources as well as /// unmanaged resources. /// If disposing is false only clean up unmanaged resources. /// </summary> /// <param name="disposing">Indicates whether or not to dispose /// managed resources.</param> private void Dispose(bool disposing) { if (!this.isDisposed) { lock (this.disposeLock) { // We got the lock, isDisposed is true, means that the disposing has been finished. if (this.isDisposed) { return; } this.isDisposed = true; this.CancelWork(); this.WaitForCompletion(); if (disposing) { if (null != this.controllerQueue) { this.controllerQueue.Dispose(); this.controllerQueue = null; } if (null != this.cancellationTokenSource) { this.cancellationTokenSource.Dispose(); this.cancellationTokenSource = null; } if (null != this.controllerResetEvent) { this.controllerResetEvent.Dispose(); this.controllerResetEvent = null; } if (null != this.scheduleSemaphore) { this.scheduleSemaphore.Dispose(); this.scheduleSemaphore = null; } this.memoryManager = null; } } } else { this.WaitForCompletion(); } }
public static byte[] RequireBuffer(MemoryManager memoryManager, Action checkCancellation) { byte[] buffer; buffer = memoryManager.RequireBuffer(); if (null == buffer) { int retryCount = 0; int retryInterval = 100; while ((retryCount < RequireBufferMaxRetryCount) && (null == buffer)) { checkCancellation(); retryInterval <<= 1; Thread.Sleep(retryInterval); buffer = memoryManager.RequireBuffer(); ++retryCount; } } if (null == buffer) { throw new TransferException( TransferErrorCode.FailToAllocateMemory, Resources.FailedToAllocateMemoryException); } return buffer; }
public TransferDownloadStream(MemoryManager memoryManager, TransferDownloadBuffer buffer, int offset, int count) :this(memoryManager, buffer, offset, count, null, 0, 0) { }
public TransferData(MemoryManager memoryManager) { this.memoryManager = memoryManager; }
/// <summary> /// Calculate MD5 hash of transferred bytes. /// </summary> /// <param name="memoryManager">Reference to MemoryManager object to require buffer from.</param> /// <param name="checkCancellation">Action to check whether to cancel this calculation.</param> public void CalculateMd5(MemoryManager memoryManager, Action checkCancellation) { if (null == this.md5hash) { return; } byte[] buffer = null; try { buffer = Utils.RequireBuffer(memoryManager, checkCancellation); } catch (Exception) { lock (this.md5hash) { this.finishedSeparateMd5Calculator = true; } throw; } long offset = 0; int readLength = 0; while (true) { lock (this.md5hash) { if (offset >= this.md5hashOffset) { Debug.Assert( offset == this.md5hashOffset, "We should stop the separate calculator thread just at the transferred offset"); this.succeededSeparateMd5Calculator = true; this.finishedSeparateMd5Calculator = true; break; } readLength = (int)Math.Min(this.md5hashOffset - offset, buffer.Length); } try { checkCancellation(); readLength = this.Read(offset, buffer, 0, readLength); lock (this.md5hash) { this.md5hash.TransformBlock(buffer, 0, readLength, null, 0); } } catch (Exception) { lock (this.md5hash) { this.finishedSeparateMd5Calculator = true; } memoryManager.ReleaseBuffer(buffer); throw; } offset += readLength; } memoryManager.ReleaseBuffer(buffer); }
/// <summary> /// Calculate MD5 hash of transferred bytes. /// </summary> /// <param name="memoryManager">Reference to MemoryManager object to require buffer from.</param> /// <param name="checkCancellation">Action to check whether to cancel this calculation.</param> public void CalculateMd5(MemoryManager memoryManager, Action checkCancellation) { if (null == this.md5hash) { return; } byte[] buffer = null; try { buffer = Utils.RequireBuffer(memoryManager, checkCancellation); } catch (Exception) { lock (this.md5hash) { this.finishedSeparateMd5Calculator = true; } throw; } long offset = 0; int readLength = 0; while (true) { lock (this.md5hash) { if (offset >= this.md5hashOffset) { Debug.Assert( offset == this.md5hashOffset, "We should stop the separate calculator thread just at the transferred offset"); this.succeededSeparateMd5Calculator = true; this.finishedSeparateMd5Calculator = true; break; } readLength = (int)Math.Min(this.md5hashOffset - offset, buffer.Length); } try { checkCancellation(); readLength = this.Read(offset, buffer, 0, readLength); lock (this.md5hash) { this.md5hash.UpdateHash(buffer, 0, readLength); } } catch (Exception) { lock (this.md5hash) { this.finishedSeparateMd5Calculator = true; } memoryManager.ReleaseBuffer(buffer); throw; } offset += readLength; } memoryManager.ReleaseBuffer(buffer); }