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 Queue workQueue = 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
- ToolConsole.cs
- PackageDigitalSignature.cs
- OletxEnlistment.cs
- KeyValuePairs.cs
- ContextStaticAttribute.cs
- PersonalizationStateInfoCollection.cs
- CodeCatchClauseCollection.cs
- TransformGroup.cs
- RequestCache.cs
- TemplateControlCodeDomTreeGenerator.cs
- ReversePositionQuery.cs
- ComContractElement.cs
- XPathNavigatorReader.cs
- FileDataSourceCache.cs
- invalidudtexception.cs
- DocumentApplication.cs
- fixedPageContentExtractor.cs
- OpCodes.cs
- StorageScalarPropertyMapping.cs
- FilterableData.cs
- Int64Storage.cs
- CacheDependency.cs
- UIElementPropertyUndoUnit.cs
- StylusPointCollection.cs
- SqlDataSourceStatusEventArgs.cs
- WindowsSysHeader.cs
- PrivilegeNotHeldException.cs
- TableItemStyle.cs
- FlowDocumentView.cs
- BasicKeyConstraint.cs
- ISAPIApplicationHost.cs
- UpdateExpressionVisitor.cs
- Int32.cs
- DataGridLinkButton.cs
- _AutoWebProxyScriptWrapper.cs
- SqlPersistenceWorkflowInstanceDescription.cs
- PathGeometry.cs
- StringFreezingAttribute.cs
- SvcMapFileLoader.cs
- CodeConstructor.cs
- XmlTypeAttribute.cs
- SoapDocumentMethodAttribute.cs
- Range.cs
- ProfileSettings.cs
- TcpChannelHelper.cs
- Assign.cs
- PerspectiveCamera.cs
- DbProviderFactoriesConfigurationHandler.cs
- Compiler.cs
- HtmlInputPassword.cs
- Version.cs
- NumericUpDownAcceleration.cs
- DecoderExceptionFallback.cs
- CacheRequest.cs
- Visual3D.cs
- BaseDataListPage.cs
- COM2AboutBoxPropertyDescriptor.cs
- AttachmentService.cs
- Opcode.cs
- LockCookie.cs
- RIPEMD160Managed.cs
- TraceEventCache.cs
- xsdvalidator.cs
- SimpleExpression.cs
- DataServiceRequest.cs
- BaseTemplateCodeDomTreeGenerator.cs
- ProcessHostFactoryHelper.cs
- XmlSerializerFactory.cs
- AssemblyHash.cs
- PropertyFilter.cs
- XmlSchemaSimpleContent.cs
- ScrollableControl.cs
- DataGridViewColumnEventArgs.cs
- Comparer.cs
- TextReader.cs
- X509Certificate2.cs
- Registration.cs
- WorkflowInstance.cs
- HttpListenerPrefixCollection.cs
- LabelDesigner.cs
- StyleSheet.cs
- QuaternionRotation3D.cs
- ControlPaint.cs
- Run.cs
- WindowsGraphics.cs
- DispatcherHooks.cs
- CustomAttributeFormatException.cs
- TextWriter.cs
- EntityDataSourceUtil.cs
- BitmapCache.cs
- DbParameterCollection.cs
- HealthMonitoringSectionHelper.cs
- QueryResponse.cs
- ConfigurationStrings.cs
- TypeSystem.cs
- SecurityContextSecurityTokenParameters.cs
- TypeValidationEventArgs.cs
- SynchronousChannelMergeEnumerator.cs
- FileUtil.cs
- TypeConverter.cs