Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Channels / IOThreadScheduler.cs / 1 / IOThreadScheduler.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace System.ServiceModel.Channels { using Microsoft.Win32.SafeHandles; using System.Collections.Generic; using System.IO; using System.Runtime.InteropServices; using System.Security; using System.ServiceModel.Diagnostics; using System.Threading; using System.Security.Permissions; static class IOThreadScheduler { ////// Critical - calls into critical class CriticalHelper /// Safe - ensures that SecurityContext flows across the thread switch /// [SecurityCritical, SecurityTreatAsSafe] public static void ScheduleCallback(WaitCallback callback, object state) { CriticalHelper.ScheduleCallback(callback, state, true, false); } // The low-pri queue is susceptable to starvation if executing codepaths are dependent on the low-pri task. // Only use the low-pri queue for new requests or similarly isolated tasks. // ////// Critical - calls into critical class CriticalHelper, doesn't flow context /// [SecurityCritical] public static void ScheduleCallbackLowPriNoFlow(WaitCallback callback, object state) { CriticalHelper.ScheduleCallback(callback, state, false, true); } ////// Critical - must correctly capture SecurityContext and re-apply on callback /// [SecurityCritical(SecurityCriticalScope.Everything)] static class CriticalHelper { static object lockObject = new object(); static bool queuedCompletion; static QueueworkQueue = new Queue (); static Queue lowPriQueue = new Queue (); static ScheduledOverlapped overlapped = new ScheduledOverlapped(new WaitCallback(CompletionCallback)); /// /// note that in some hosts this runs without any user context on the stack /// static void CompletionCallback(object state) { lock (lockObject) { queuedCompletion = false; } ThreadTrace.Trace("IOThreadScheduler.CompletionCallback"); ProcessCallbacks(); } ////// note that in some hosts this runs without any user context on the stack /// static void ProcessCallbacks() { while (true) { WorkItem workItem; bool needOverlappedQueued = false; try { lock (lockObject) { if (CriticalHelper.workQueue.Count != 0) { workItem = CriticalHelper.workQueue.Dequeue(); } else if (CriticalHelper.lowPriQueue.Count != 0) { workItem = CriticalHelper.lowPriQueue.Dequeue(); } else { break; } if (!queuedCompletion && (CriticalHelper.workQueue.Count > 0 || CriticalHelper.lowPriQueue.Count > 0)) { needOverlappedQueued = true; CriticalHelper.queuedCompletion = true; } } } finally { if (needOverlappedQueued) { CriticalHelper.overlapped.Post(); } } workItem.Invoke(); } } public static void ScheduleCallback(WaitCallback callback, object state, bool flow, bool lowPri) { if (callback == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentNullException("callback")); object workItemState = state; if (DiagnosticUtility.ShouldUseActivity) { // Wrap callback's state object with TracingAsyncCallbackState to // capture the current thread's ActivityID workItemState = new System.ServiceModel.Diagnostics.TraceUtility.TracingAsyncCallbackState(state); } ThreadTrace.Trace("IOThreadScheduler.ScheduleCallback"); WorkItem workItem = new WorkItem(callback, workItemState, flow); bool needOverlappedQueued = false; try { lock (lockObject) { (lowPri ? CriticalHelper.lowPriQueue : CriticalHelper.workQueue).Enqueue(workItem); if (!queuedCompletion) { needOverlappedQueued = true; CriticalHelper.queuedCompletion = true; } } } finally { if (needOverlappedQueued) { CriticalHelper.overlapped.Post(); } } } class WorkItem { static ContextCallback securityContextCallback = new ContextCallback(OnSecurityContextCallback); WaitCallback callback; object state; SecurityContext context; public WorkItem(WaitCallback callback, object state, bool flow) { this.callback = callback; this.state = state; this.context = flow ? PartialTrustHelpers.CaptureSecurityContextNoIdentityFlow() : null; } ////// note that in some hosts this runs without any user context on the stack /// public void Invoke() { if (this.context != null) { SecurityContext.Run(this.context, securityContextCallback, this); } else { Invoke2(); } } static void OnSecurityContextCallback(object o) { ((WorkItem)o).Invoke2(); } ////// note that in some hosts this runs without any user context on the stack /// void Invoke2() { // Activity tracing may have been toggled by the user after this callback was // registered (e.g. via WMI). Do not assume that since Activity tracing is on // that the state object is of type TracingAsyncCallbackState or vice versa. // Instead, try the cast using the 'as' keyword. If cast fails, asyncState's // value will be null and the following code will run as if activity tracing // is turned off. If it is not null, then do the appropriate action based // on DiagnosticUtility.ShouldUseActivity. System.ServiceModel.Diagnostics.TraceUtility.TracingAsyncCallbackState asyncState = state as System.ServiceModel.Diagnostics.TraceUtility.TracingAsyncCallbackState; if (null == asyncState) { this.callback(state); } else { using (Activity activity = DiagnosticUtility.ShouldUseActivity ? Activity.CreateActivity(asyncState.ActivityId) : null) { this.callback(asyncState.InnerState); } } } } class ScheduledOverlapped { unsafe NativeOverlapped* nativeOverlapped; WaitCallback callback; // Since we keep this object in a static, we never need to Free the overlapped, so there's no need for a finalizer. unsafe public ScheduledOverlapped(WaitCallback callback) { Overlapped overlapped = new Overlapped(0, 0, IntPtr.Zero, null); this.nativeOverlapped = overlapped.UnsafePack(DiagnosticUtility.Utility.ThunkCallback(new IOCompletionCallback(IOCallback)), null); this.callback = callback; } unsafe void IOCallback(uint errorCode, uint numBytes, NativeOverlapped* nativeOverlapped) { callback(null); } unsafe public void Post() { ThreadPool.UnsafeQueueNativeOverlapped(this.nativeOverlapped); } } } } } // 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
- TypeGeneratedEventArgs.cs
- DataGridViewControlCollection.cs
- TabPanel.cs
- SkewTransform.cs
- StylusPointProperties.cs
- SByte.cs
- XmlSchemaAttributeGroupRef.cs
- entitydatasourceentitysetnameconverter.cs
- BufferedWebEventProvider.cs
- RemotingService.cs
- DataGridViewCellStyle.cs
- ListItemConverter.cs
- GetPageCompletedEventArgs.cs
- NaturalLanguageHyphenator.cs
- DataGridViewCellStyleConverter.cs
- SQLResource.cs
- WeakEventTable.cs
- ToolStripDropDownItem.cs
- XPathNodePointer.cs
- DBAsyncResult.cs
- WebPartHeaderCloseVerb.cs
- CurrencyManager.cs
- SystemWebCachingSectionGroup.cs
- BrowserTree.cs
- DataGridViewAddColumnDialog.cs
- SqlNotificationEventArgs.cs
- InteropAutomationProvider.cs
- MSHTMLHostUtil.cs
- TextEditorTyping.cs
- HostingEnvironmentWrapper.cs
- SapiRecoContext.cs
- ObjectDataSourceStatusEventArgs.cs
- StackBuilderSink.cs
- ObjectIDGenerator.cs
- SerialStream.cs
- _CommandStream.cs
- HandlerBase.cs
- MailWebEventProvider.cs
- FrugalMap.cs
- SecUtil.cs
- ThicknessAnimationBase.cs
- ThreadAbortException.cs
- Canvas.cs
- AttachedPropertyBrowsableForTypeAttribute.cs
- ToolStripPanelRow.cs
- SecurityTokenResolver.cs
- TcpClientSocketManager.cs
- XmlAutoDetectWriter.cs
- OledbConnectionStringbuilder.cs
- GridErrorDlg.cs
- RenderContext.cs
- DataConnectionHelper.cs
- TraceSection.cs
- DynamicPropertyReader.cs
- DesignerSerializationVisibilityAttribute.cs
- TreeViewAutomationPeer.cs
- OleDbParameterCollection.cs
- KoreanCalendar.cs
- DecimalConstantAttribute.cs
- Overlapped.cs
- QueuePropertyVariants.cs
- DateTimeFormatInfoScanner.cs
- LazyTextWriterCreator.cs
- XmlSchemaParticle.cs
- XmlSchemaAnnotation.cs
- TextParaClient.cs
- HttpCacheVaryByContentEncodings.cs
- MappingSource.cs
- MDIWindowDialog.cs
- FrugalList.cs
- VisualTreeUtils.cs
- PermissionSet.cs
- StorageEndPropertyMapping.cs
- DataGridViewUtilities.cs
- CodeObject.cs
- SerialPinChanges.cs
- EncodingInfo.cs
- FilterableAttribute.cs
- ListenerChannelContext.cs
- ThemeInfoAttribute.cs
- CriticalExceptions.cs
- ThemeableAttribute.cs
- WindowsAuthenticationEventArgs.cs
- RemotingService.cs
- ParserStreamGeometryContext.cs
- AppLevelCompilationSectionCache.cs
- VerticalAlignConverter.cs
- IPEndPointCollection.cs
- HwndMouseInputProvider.cs
- GiveFeedbackEvent.cs
- LineUtil.cs
- ActivityExecutionFilter.cs
- ToolboxItemFilterAttribute.cs
- PagesSection.cs
- HttpResponseHeader.cs
- OleDbConnectionInternal.cs
- XmlCollation.cs
- NestPullup.cs
- WebEventTraceProvider.cs
- DataGridViewLinkColumn.cs