Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / Log / System / IO / Log / FileRecordSequence.cs / 1 / FileRecordSequence.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace System.IO.Log { using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Security.AccessControl; using System.Runtime.InteropServices; using System.Security.Permissions; using System.Diagnostics; using System.Threading; // FileRecordSequence uses Simple file log to write records to a file. public sealed class FileRecordSequence : IRecordSequence { SimpleFileLog log; bool retryAppend; object syncTailPinned = new object(); bool tailPinnedCalled = false; FileAccess access; FileRecordSequenceHelper frsHelper; long reservedBytes; object syncReservedBytes = new object(); int tailPinnedThreadID = -1; public FileRecordSequence(string path) : this(path, FileAccess.ReadWrite, 0) { } public FileRecordSequence(string path, FileAccess access) : this(path, access, 0) { } [PermissionSetAttribute(SecurityAction.Demand, Name="FullTrust")] public FileRecordSequence(string path, FileAccess access, int size) { if (size < 0) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ArgumentOutOfRange("size")); this.access = access; this.log = new SimpleFileLog(Path.GetFullPath(path), size); this.frsHelper = new FileRecordSequenceHelper(this.log); this.reservedBytes = 0; } public SequenceNumber BaseSequenceNumber { get { return this.frsHelper.BaseSequenceNumber; } } public SequenceNumber LastSequenceNumber { get { return this.frsHelper.LastSequenceNumber; } } public long MaximumRecordLength { get { return Int32.MaxValue; } } public long ReservedBytes { get { return this.reservedBytes; } } public bool RetryAppend { get { return this.retryAppend; } set { this.retryAppend = value; } } public SequenceNumber RestartSequenceNumber { get { return this.frsHelper.RestartSequenceNumber; } } public event EventHandlerTailPinned; public void AdvanceBaseSequenceNumber( SequenceNumber newBaseSequenceNumber) { this.frsHelper.AdvanceBaseSequeceNumber(newBaseSequenceNumber); } internal void AddReservation(long reservation) { lock (this.syncReservedBytes) { this.reservedBytes += reservation; } } internal void RemoveReservation(long reservation) { lock (this.syncReservedBytes) { this.reservedBytes -= reservation; } } public SequenceNumber Append( ArraySegment data, SequenceNumber nextUndoRecord, SequenceNumber previousRecord, RecordAppendOptions recordAppendOptions) { return Append(new ArraySegment [] { data }, nextUndoRecord, previousRecord, recordAppendOptions); } public SequenceNumber Append( ArraySegment data, SequenceNumber nextUndoRecord, SequenceNumber previousRecord, RecordAppendOptions recordAppendOptions, ReservationCollection reservations) { return Append(new ArraySegment [] { data }, nextUndoRecord, previousRecord, recordAppendOptions, reservations); } public SequenceNumber Append( IList > data, SequenceNumber nextUndoRecord, SequenceNumber previousRecord, RecordAppendOptions recordAppendOptions) { if (data == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ArgumentNull("data")); } if ((this.access & FileAccess.Write) == 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.NotSupported(SR.NotSupported_ReadOnly)); } if(recordAppendOptions > (RecordAppendOptions.ForceAppend | RecordAppendOptions.ForceFlush) || recordAppendOptions < RecordAppendOptions.None) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ArgumentOutOfRange("recordAppendOptions")); } SequenceNumber sn; bool forceFlush = (recordAppendOptions & RecordAppendOptions.ForceFlush) != 0; try { sn = frsHelper.Append(data, nextUndoRecord, previousRecord, forceFlush); } catch (SequenceFullException) { RaiseTailPinnedEvent(); if (this.RetryAppend) { sn = frsHelper.Append(data, nextUndoRecord, previousRecord, forceFlush); } else { throw; } } return sn; } public SequenceNumber Append( IList > data, SequenceNumber nextUndoRecord, SequenceNumber previousRecord, RecordAppendOptions recordAppendOptions, ReservationCollection reservations) { int size = 0; if (reservations == null) { return Append(data, nextUndoRecord, previousRecord, recordAppendOptions); } if (data == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ArgumentNull("data")); } FileReservationCollection reservationCollection = reservations as FileReservationCollection; if (reservationCollection == null || !reservationCollection.IsMyCollection(this)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ArgumentInvalid(SR.LogRecSeq_InvalidReservationCollection)); } for (int i = 0; i < data.Count; i++) { size += data[i].Count; } long reservation = reservationCollection.GetBestMatchingReservation(size); if (reservation < 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ReservationNotFound()); } bool throwing = true; try { SequenceNumber returnValue = this.Append(data, nextUndoRecord, previousRecord, recordAppendOptions); throwing = false; return returnValue; } finally { if (throwing) { reservationCollection.Add(reservation); } } } public IAsyncResult BeginAppend( ArraySegment data, SequenceNumber nextUndoRecord, SequenceNumber previousRecord, RecordAppendOptions recordAppendOptions, AsyncCallback callback, object state) { return BeginAppend(new ArraySegment [] { data }, nextUndoRecord, previousRecord, recordAppendOptions, callback, state); } public IAsyncResult BeginAppend( ArraySegment data, SequenceNumber nextUndoRecord, SequenceNumber previousRecord, RecordAppendOptions recordAppendOptions, ReservationCollection reservations, AsyncCallback callback, object state) { return BeginAppend(new ArraySegment [] { data }, nextUndoRecord, previousRecord, recordAppendOptions, reservations, callback, state); } public IAsyncResult BeginAppend( IList > data, SequenceNumber nextUndoRecord, SequenceNumber previousRecord, RecordAppendOptions recordAppendOptions, AsyncCallback callback, object state) { SequenceNumber result = Append(data, nextUndoRecord, previousRecord, recordAppendOptions); return new FileRecordSequenceCompletedAsyncResult(result, callback, state, Work.Append); } public IAsyncResult BeginAppend( IList > data, SequenceNumber nextUndoRecord, SequenceNumber previousRecord, RecordAppendOptions recordAppendOptions, ReservationCollection reservations, AsyncCallback callback, object state) { SequenceNumber result = Append(data, nextUndoRecord, previousRecord, recordAppendOptions, reservations); return new FileRecordSequenceCompletedAsyncResult(result, callback, state, Work.Append); } public IAsyncResult BeginFlush( SequenceNumber sequenceNumber, AsyncCallback callback, object state) { SequenceNumber result = this.Flush(sequenceNumber); return new FileRecordSequenceCompletedAsyncResult(result, callback, state, Work.Flush); } public IAsyncResult BeginReserveAndAppend( ArraySegment data, SequenceNumber nextUndoRecord, SequenceNumber previousRecord, RecordAppendOptions recordAppendOptions, ReservationCollection reservationCollection, long[] reservations, AsyncCallback callback, object state) { return BeginReserveAndAppend(new ArraySegment [] { data }, nextUndoRecord, previousRecord, recordAppendOptions, reservationCollection, reservations, callback, state); } public IAsyncResult BeginReserveAndAppend( IList > data, SequenceNumber nextUndoRecord, SequenceNumber previousRecord, RecordAppendOptions recordAppendOptions, ReservationCollection reservationCollection, long[] reservations, AsyncCallback callback, object state) { SequenceNumber result = ReserveAndAppend( data, nextUndoRecord, previousRecord, recordAppendOptions, reservationCollection, reservations); return new FileRecordSequenceCompletedAsyncResult(result, callback, state, Work.ReserveAndAppend); } public IAsyncResult BeginWriteRestartArea( ArraySegment data, SequenceNumber newBaseSeqNum, ReservationCollection reservation, AsyncCallback callback, object state) { return BeginWriteRestartArea(new ArraySegment [] { data }, newBaseSeqNum, reservation, callback, state); } public IAsyncResult BeginWriteRestartArea( IList > data, SequenceNumber newBaseSeqNum, ReservationCollection reservation, AsyncCallback callback, object state) { SequenceNumber result = WriteRestartArea(data, newBaseSeqNum, reservation); return new FileRecordSequenceCompletedAsyncResult(result, callback, state, Work.WriteRestartArea); } public ReservationCollection CreateReservationCollection() { FileReservationCollection collection = new FileReservationCollection(this); return collection; } public void Dispose() { this.log.Close(); } public SequenceNumber EndAppend( IAsyncResult result) { FileRecordSequenceCompletedAsyncResult asyncResult = result as FileRecordSequenceCompletedAsyncResult; if (asyncResult == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ArgumentInvalid(SR.AsyncResult_Invalid)); } if (asyncResult.CompletedWork != Work.Append) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ArgumentInvalid(SR.AsyncResult_Invalid)); } return asyncResult.End(); } public SequenceNumber EndFlush( IAsyncResult result) { FileRecordSequenceCompletedAsyncResult asyncResult = result as FileRecordSequenceCompletedAsyncResult; if (asyncResult == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ArgumentInvalid(SR.AsyncResult_Invalid)); } if (asyncResult.CompletedWork != Work.Flush) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ArgumentInvalid(SR.AsyncResult_Invalid)); } return asyncResult.End(); } public SequenceNumber EndReserveAndAppend( IAsyncResult result) { FileRecordSequenceCompletedAsyncResult asyncResult = result as FileRecordSequenceCompletedAsyncResult; if (asyncResult == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ArgumentInvalid(SR.AsyncResult_Invalid)); } if (asyncResult.CompletedWork != Work.ReserveAndAppend) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ArgumentInvalid(SR.AsyncResult_Invalid)); } return asyncResult.End(); } public SequenceNumber EndWriteRestartArea( IAsyncResult result) { FileRecordSequenceCompletedAsyncResult asyncResult = result as FileRecordSequenceCompletedAsyncResult; if (asyncResult == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ArgumentInvalid(SR.AsyncResult_Invalid)); } if (asyncResult.CompletedWork != Work.WriteRestartArea) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ArgumentInvalid(SR.AsyncResult_Invalid)); } return asyncResult.End(); } public SequenceNumber Flush() { return this.Flush(SequenceNumber.Invalid); } public SequenceNumber Flush(SequenceNumber sequenceNumber) { return this.frsHelper.Flush(sequenceNumber); } // The first thread raises the tail pinned event. // All other threads wait until first thread finishes. private void RaiseTailPinnedEvent() { bool raiseEvent; Monitor.Enter(this.syncTailPinned); try { if (this.tailPinnedCalled) { if(this.tailPinnedThreadID == Thread.CurrentThread.ManagedThreadId) { // This is the same thread where RaiseTailPinnedEvent() was called and user // tried an Append or WriteRestartArea in the TailPinned callback. // Let the first call complete... // Trying to prevent deadlock... return; } else { // This is not the first thread. Wait until the first thread has handled tail pinned raiseEvent = false; Monitor.Wait(this.syncTailPinned); } } else { // First thread. Raise the event. this.tailPinnedCalled = true; raiseEvent = true; this.tailPinnedThreadID = Thread.CurrentThread.ManagedThreadId; } } finally { Monitor.Exit(this.syncTailPinned); } if (raiseEvent) { // First thread raises the event. Signals other waiting threads when done. try { EventHandler handler; handler = this.TailPinned; if (handler != null) { try { handler(this, new TailPinnedEventArgs(this.LastSequenceNumber)); } #pragma warning suppress 56500 // This is a callback exception catch (Exception exception) { if (DiagnosticUtility.IsFatal(exception)) throw; throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(exception); } } } finally { Monitor.Enter(this.syncTailPinned); try { this.tailPinnedCalled = false; this.tailPinnedThreadID = -1; // Signal waiting threads Monitor.PulseAll(this.syncTailPinned); } finally { Monitor.Exit(this.syncTailPinned); } } } } public IEnumerable ReadLogRecords( SequenceNumber start, LogRecordEnumeratorType logRecordEnum) { if ((this.access & FileAccess.Read) == 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.NotSupported(SR.NotSupported_WriteOnly)); } if (logRecordEnum < LogRecordEnumeratorType.User || logRecordEnum > LogRecordEnumeratorType.Next) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ArgumentOutOfRange("logRecordEnum")); } return new FileLogRecordEnumerable(this.log, start, logRecordEnum, false); } public IEnumerable ReadRestartAreas() { if ((this.access & FileAccess.Read) == 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.NotSupported(SR.NotSupported_WriteOnly)); } return new FileLogRecordEnumerable( this.log, this.frsHelper.RestartSequenceNumber, LogRecordEnumeratorType.Previous, true); } public SequenceNumber ReserveAndAppend( ArraySegment data, SequenceNumber nextUndoRecord, SequenceNumber previousRecord, RecordAppendOptions recordAppendOptions, ReservationCollection reservationCollection, params long[] reservations) { return ReserveAndAppend(new ArraySegment [] { data }, nextUndoRecord, previousRecord, recordAppendOptions, reservationCollection, reservations); } public SequenceNumber ReserveAndAppend( IList > data, SequenceNumber nextUndoRecord, SequenceNumber previousRecord, RecordAppendOptions recordAppendOptions, ReservationCollection reservationCollection, params long[] reservations) { if (reservationCollection == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ArgumentNull("reservationCollection")); } if (reservations == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ArgumentNull("reservations")); } FileReservationCollection fileResCollection = null; fileResCollection = reservationCollection as FileReservationCollection; if (fileResCollection == null || !fileResCollection.IsMyCollection(this)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ArgumentInvalid(SR.LogRecSeq_InvalidReservationCollection)); } foreach (long reservationSize in reservations) { if (reservationSize < 0) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ArgumentOutOfRange("reservations")); } foreach (long reservationSize in reservations) { fileResCollection.Add(reservationSize); } bool throwing = true; try { SequenceNumber returnValue = Append(data, nextUndoRecord, previousRecord, recordAppendOptions); throwing = false; return returnValue; } finally { if (throwing && fileResCollection != null) { foreach (long reservationSize in reservations) { fileResCollection.Remove(reservationSize); } } } } public SequenceNumber WriteRestartArea( ArraySegment data) { return WriteRestartArea(new ArraySegment [] { data }); } public SequenceNumber WriteRestartArea( ArraySegment data, SequenceNumber newBaseSeqNum) { return WriteRestartArea(new ArraySegment [] { data }, newBaseSeqNum); } public SequenceNumber WriteRestartArea( ArraySegment data, SequenceNumber newBaseSeqNum, ReservationCollection reservations) { return WriteRestartArea(new ArraySegment [] { data }, newBaseSeqNum, reservations); } public SequenceNumber WriteRestartArea( IList > data) { return WriteRestartArea(data, this.BaseSequenceNumber); } public SequenceNumber WriteRestartArea( IList > data, SequenceNumber newBaseSeqNum) { if(newBaseSeqNum == SequenceNumber.Invalid) { newBaseSeqNum = this.BaseSequenceNumber; } try { return this.frsHelper.WriteRestartAreaInternal(data, newBaseSeqNum); } catch (SequenceFullException) { RaiseTailPinnedEvent(); if (this.RetryAppend) { return this.frsHelper.WriteRestartAreaInternal(data, newBaseSeqNum); } else { throw; } } } public SequenceNumber WriteRestartArea( IList > data, SequenceNumber newBaseSeqNum, ReservationCollection reservations) { long size = 0; if(data == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ArgumentNull("data")); } if (reservations == null) return WriteRestartArea(data, newBaseSeqNum); FileReservationCollection reservationCollection = reservations as FileReservationCollection; if (reservationCollection == null || !reservationCollection.IsMyCollection(this)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ArgumentInvalid(SR.LogRecSeq_InvalidReservationCollection)); } for (int i = 0; i < data.Count; i++) { size = checked(size + data[i].Count); } long reservation = reservationCollection.GetBestMatchingReservation(size); if (reservation < 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ReservationNotFound()); } bool throwing = true; try { SequenceNumber returnValue = WriteRestartArea(data, newBaseSeqNum); throwing = false; return returnValue; } finally { if (throwing) { reservationCollection.Add(reservation); } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- DetailsViewInsertedEventArgs.cs
- MapPathBasedVirtualPathProvider.cs
- LoggedException.cs
- EdmSchemaError.cs
- XslCompiledTransform.cs
- HttpWrapper.cs
- FormatControl.cs
- BitmapData.cs
- DataGridItemEventArgs.cs
- ItemCollection.cs
- IteratorDescriptor.cs
- ExpressionEditorAttribute.cs
- OrderPreservingPipeliningSpoolingTask.cs
- WindowsComboBox.cs
- ToolboxComponentsCreatedEventArgs.cs
- FatalException.cs
- StickyNoteAnnotations.cs
- FeatureAttribute.cs
- HMACRIPEMD160.cs
- UserPreferenceChangingEventArgs.cs
- Double.cs
- TemplatePagerField.cs
- SqlDesignerDataSourceView.cs
- BuildProvider.cs
- GlobalizationAssembly.cs
- PostBackTrigger.cs
- ScrollEvent.cs
- UriTemplateTrieNode.cs
- TraceUtils.cs
- DesignerSerializerAttribute.cs
- AttachedPropertyBrowsableAttribute.cs
- Pkcs9Attribute.cs
- SwitchExpression.cs
- WebPartAddingEventArgs.cs
- InheritedPropertyChangedEventArgs.cs
- AdPostCacheSubstitution.cs
- BackgroundWorker.cs
- _HeaderInfoTable.cs
- NativeMethods.cs
- FormsAuthenticationEventArgs.cs
- CookieParameter.cs
- DbConnectionOptions.cs
- ResourceProviderFactory.cs
- DefaultValueTypeConverter.cs
- QilLoop.cs
- DataSourceCache.cs
- CorrelationService.cs
- OutputCacheSection.cs
- SqlException.cs
- BezierSegment.cs
- TextDecorationCollection.cs
- InternalSafeNativeMethods.cs
- MailDefinitionBodyFileNameEditor.cs
- WebBrowsableAttribute.cs
- BuildProviderCollection.cs
- QuerySettings.cs
- WSSecurityPolicy11.cs
- SqlUserDefinedAggregateAttribute.cs
- SecurityTokenAuthenticator.cs
- GridViewRowPresenter.cs
- FolderBrowserDialog.cs
- DesignerEditorPartChrome.cs
- BitmapPalettes.cs
- ListViewCancelEventArgs.cs
- TemplatePagerField.cs
- XmlSchemaElement.cs
- DescendantQuery.cs
- DeclarationUpdate.cs
- MetadataCollection.cs
- propertytag.cs
- SqlDataSourceAdvancedOptionsForm.cs
- ResourceDefaultValueAttribute.cs
- PermissionToken.cs
- Ray3DHitTestResult.cs
- ApplicationGesture.cs
- httpstaticobjectscollection.cs
- DataServiceExpressionVisitor.cs
- StaticFileHandler.cs
- SinglePageViewer.cs
- XmlReader.cs
- Facet.cs
- SerializableAttribute.cs
- DocumentApplication.cs
- Pair.cs
- AsnEncodedData.cs
- GeneratedCodeAttribute.cs
- StructuredTypeEmitter.cs
- MTConfigUtil.cs
- TreeNode.cs
- OrderingExpression.cs
- WindowsPen.cs
- HighContrastHelper.cs
- GridView.cs
- TraceData.cs
- QilList.cs
- SupportsEventValidationAttribute.cs
- ButtonChrome.cs
- XsdDataContractImporter.cs
- ZoneMembershipCondition.cs
- dataprotectionpermission.cs