Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / ndp / fx / src / xsp / System / Web / Compilation / CompilationLock.cs / 1 / CompilationLock.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- //#define MUTEXINSTRUMENTATION namespace System.Web.Compilation { using System; using System.Threading; using System.Globalization; using System.Security.Principal; using System.Web.Util; using System.Web.Configuration; using System.Runtime.InteropServices; using System.Web.Management; using System.Runtime.Versioning; using System.Diagnostics; using Debug = System.Web.Util.Debug; internal sealed class CompilationMutex : IDisposable { private String _name; private String _comment; #if MUTEXINSTRUMENTATION // Used to keep track of the stack when the mutex is obtained private string _stackTrace; #endif // ROTORTODO: replace unmanaged aspnet_isapi mutex with managed implementation #if !FEATURE_PAL // No unmanaged aspnet_isapi mutex in Coriolis private HandleRef _mutexHandle; // Lock Status is used to drain out all worker threads out of Mutex ownership on // app domain shutdown: -1 locked for good, 0 unlocked, N locked by a worker thread(s) private int _lockStatus; private bool _draining = false; #endif // !FEATURE_PAL internal CompilationMutex(String name, String comment) { #if !FEATURE_PAL // No unmanaged aspnet_isapi mutex in Coriolis // Attempt to get the mutex string from the registry (VSWhidbey 415795) string mutexRandomName = (string) Misc.GetAspNetRegValue("CompilationMutexName", null /*valueName*/, null /*defaultValue*/); if (mutexRandomName != null) { // If we were able to use the registry value, use it. Also, we need to prepend "Global\" // to the mutex name, to make sure it can be shared between a terminal server session // and IIS (VSWhidbey 307523). _name += @"Global\" + name + "-" + mutexRandomName; } else { // If we couldn't get the reg value, don't use it, and prepend "Local\" to the mutex // name to make it local to the session (and hence prevent hijacking) _name += @"Local\" + name; } _comment = comment; Debug.Trace("Mutex", "Creating Mutex " + MutexDebugName); _mutexHandle = new HandleRef(this, UnsafeNativeMethods.InstrumentedMutexCreate(_name)); if (_mutexHandle.Handle == IntPtr.Zero) { Debug.Trace("Mutex", "Failed to create Mutex " + MutexDebugName); throw new InvalidOperationException(SR.GetString(SR.CompilationMutex_Create)); } Debug.Trace("Mutex", "Successfully created Mutex " + MutexDebugName); #endif // !FEATURE_PAL } ~CompilationMutex() { Close(); } void IDisposable.Dispose() { Close(); System.GC.SuppressFinalize(this); } internal /*public*/ void Close() { #if !FEATURE_PAL // No unmanaged aspnet_isapi mutex in Coriolis if (_mutexHandle.Handle != IntPtr.Zero) { UnsafeNativeMethods.InstrumentedMutexDelete(_mutexHandle); _mutexHandle = new HandleRef(this, IntPtr.Zero); } #endif // !FEATURE_PAL } [ResourceExposure(ResourceScope.None)] internal /*public*/ void WaitOne() { #if !FEATURE_PAL // No unmanaged aspnet_isapi mutex in Coriolis if (_mutexHandle.Handle == IntPtr.Zero) throw new InvalidOperationException(SR.GetString(SR.CompilationMutex_Null)); // check the lock status for (;;) { int lockStatus = _lockStatus; if (lockStatus == -1 || _draining) throw new InvalidOperationException(SR.GetString(SR.CompilationMutex_Drained)); if (Interlocked.CompareExchange(ref _lockStatus, lockStatus+1, lockStatus) == lockStatus) break; // got the lock } Debug.Trace("Mutex", "Waiting for mutex " + MutexDebugName); if (UnsafeNativeMethods.InstrumentedMutexGetLock(_mutexHandle, -1) == -1) { // failed to get the lock Interlocked.Decrement(ref _lockStatus); throw new InvalidOperationException(SR.GetString(SR.CompilationMutex_Failed)); } #if MUTEXINSTRUMENTATION // Remember the stack trace for debugging purpose _stackTrace = (new StackTrace()).ToString(); #endif Debug.Trace("Mutex", "Got mutex " + MutexDebugName); #endif // !FEATURE_PAL } #if UNUSED_CODE internal bool CheckOrFail() { #if !FEATURE_PAL // No unmanaged aspnet_isapi mutex in Coriolis if (_mutexHandle.Handle == IntPtr.Zero) throw new InvalidOperationException(SR.GetString(SR.CompilationMutex_Null)); // check the lock status for (;;) { int lockStatus = _lockStatus; if (lockStatus == -1 || _draining) throw new InvalidOperationException(SR.GetString(SR.CompilationMutex_Drained)); if (Interlocked.CompareExchange(ref _lockStatus, lockStatus+1, lockStatus) == lockStatus) break; // got the lock } Debug.Trace("Mutex", "Checking on mutex " + MutexDebugName); if (UnsafeNativeMethods.InstrumentedMutexGetLock(_mutexHandle, 0) == -1) { // failed to get the lock Debug.Trace("Mutex", "Didn't get mutex " + MutexDebugName); Interlocked.Decrement(ref _lockStatus); return false; } Debug.Trace("Mutex", "Got mutex " + MutexDebugName); return true; #else return false; #endif // !FEATURE_PAL } #endif internal /*public*/ void ReleaseMutex() { #if !FEATURE_PAL // No unmanaged aspnet_isapi mutex in Coriolis if (_mutexHandle.Handle == IntPtr.Zero) throw new InvalidOperationException(SR.GetString(SR.CompilationMutex_Null)); Debug.Trace("Mutex", "Releasing mutex " + MutexDebugName); #if MUTEXINSTRUMENTATION // Clear out the stack trace _stackTrace = null; #endif if (UnsafeNativeMethods.InstrumentedMutexReleaseLock(_mutexHandle) != 0) Interlocked.Decrement(ref _lockStatus); #endif // !FEATURE_PAL } #if UNUSED internal /*public*/ void DrainMutex() { #if !FEATURE_PAL // No unmanaged aspnet_isapi mutex in Coriolis // keep trying to set _lockStatus to -1 if it is 0 Debug.Trace("Mutex", "Starting draining mutex " + MutexDebugName); _draining = true; for (;;) { if (_lockStatus == -1) break; if (Interlocked.CompareExchange(ref _lockStatus, -1, 0) == 0) break; // got it Thread.Sleep(100); } Debug.Trace("Mutex", "Completed drained mutex " + MutexDebugName); #endif // !FEATURE_PAL } internal /*public*/ void SetState(int state) { #if !FEATURE_PAL // No unmanaged aspnet_isapi mutex in Coriolis if (_mutexHandle.Handle != IntPtr.Zero) UnsafeNativeMethods.InstrumentedMutexSetState(_mutexHandle, state); #endif // FEATURE_PAL } #endif private String MutexDebugName { get { #if DBG return (_comment != null) ? _name + " (" + _comment + ")" : _name; #else return _name; #endif } } } internal static class CompilationLock { private static CompilationMutex _mutex; static CompilationLock() { // Create the mutex (or just get it if another process created it). // Make the mutex unique per application int hashCode = ("CompilationLock" + HttpRuntime.AppDomainAppIdInternal.ToLower(CultureInfo.InvariantCulture)).GetHashCode(); _mutex = new CompilationMutex( "CL" + hashCode.ToString("x", CultureInfo.InvariantCulture), "CompilationLock for " + HttpRuntime.AppDomainAppVirtualPath); } internal static void GetLock(ref bool gotLock) { // The idea of this try/finally is to make sure that the statements are always // executed together (VSWhidbey 319154) // This code should be using a constrained execution region. try { } finally { // Always take the BuildManager lock *before* taking the mutex, to avoid possible // deadlock situations (VSWhidbey 530732) Monitor.Enter(BuildManager.TheBuildManager); _mutex.WaitOne(); gotLock = true; } } internal static void ReleaseLock() { _mutex.ReleaseMutex(); Monitor.Exit(BuildManager.TheBuildManager); } #if UNUSED internal static void DrainMutex() { _mutex.DrainMutex(); } internal static void SetMutexState(int state) { _mutex.SetState(state); } #endif } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- //#define MUTEXINSTRUMENTATION namespace System.Web.Compilation { using System; using System.Threading; using System.Globalization; using System.Security.Principal; using System.Web.Util; using System.Web.Configuration; using System.Runtime.InteropServices; using System.Web.Management; using System.Runtime.Versioning; using System.Diagnostics; using Debug = System.Web.Util.Debug; internal sealed class CompilationMutex : IDisposable { private String _name; private String _comment; #if MUTEXINSTRUMENTATION // Used to keep track of the stack when the mutex is obtained private string _stackTrace; #endif // ROTORTODO: replace unmanaged aspnet_isapi mutex with managed implementation #if !FEATURE_PAL // No unmanaged aspnet_isapi mutex in Coriolis private HandleRef _mutexHandle; // Lock Status is used to drain out all worker threads out of Mutex ownership on // app domain shutdown: -1 locked for good, 0 unlocked, N locked by a worker thread(s) private int _lockStatus; private bool _draining = false; #endif // !FEATURE_PAL internal CompilationMutex(String name, String comment) { #if !FEATURE_PAL // No unmanaged aspnet_isapi mutex in Coriolis // Attempt to get the mutex string from the registry (VSWhidbey 415795) string mutexRandomName = (string) Misc.GetAspNetRegValue("CompilationMutexName", null /*valueName*/, null /*defaultValue*/); if (mutexRandomName != null) { // If we were able to use the registry value, use it. Also, we need to prepend "Global\" // to the mutex name, to make sure it can be shared between a terminal server session // and IIS (VSWhidbey 307523). _name += @"Global\" + name + "-" + mutexRandomName; } else { // If we couldn't get the reg value, don't use it, and prepend "Local\" to the mutex // name to make it local to the session (and hence prevent hijacking) _name += @"Local\" + name; } _comment = comment; Debug.Trace("Mutex", "Creating Mutex " + MutexDebugName); _mutexHandle = new HandleRef(this, UnsafeNativeMethods.InstrumentedMutexCreate(_name)); if (_mutexHandle.Handle == IntPtr.Zero) { Debug.Trace("Mutex", "Failed to create Mutex " + MutexDebugName); throw new InvalidOperationException(SR.GetString(SR.CompilationMutex_Create)); } Debug.Trace("Mutex", "Successfully created Mutex " + MutexDebugName); #endif // !FEATURE_PAL } ~CompilationMutex() { Close(); } void IDisposable.Dispose() { Close(); System.GC.SuppressFinalize(this); } internal /*public*/ void Close() { #if !FEATURE_PAL // No unmanaged aspnet_isapi mutex in Coriolis if (_mutexHandle.Handle != IntPtr.Zero) { UnsafeNativeMethods.InstrumentedMutexDelete(_mutexHandle); _mutexHandle = new HandleRef(this, IntPtr.Zero); } #endif // !FEATURE_PAL } [ResourceExposure(ResourceScope.None)] internal /*public*/ void WaitOne() { #if !FEATURE_PAL // No unmanaged aspnet_isapi mutex in Coriolis if (_mutexHandle.Handle == IntPtr.Zero) throw new InvalidOperationException(SR.GetString(SR.CompilationMutex_Null)); // check the lock status for (;;) { int lockStatus = _lockStatus; if (lockStatus == -1 || _draining) throw new InvalidOperationException(SR.GetString(SR.CompilationMutex_Drained)); if (Interlocked.CompareExchange(ref _lockStatus, lockStatus+1, lockStatus) == lockStatus) break; // got the lock } Debug.Trace("Mutex", "Waiting for mutex " + MutexDebugName); if (UnsafeNativeMethods.InstrumentedMutexGetLock(_mutexHandle, -1) == -1) { // failed to get the lock Interlocked.Decrement(ref _lockStatus); throw new InvalidOperationException(SR.GetString(SR.CompilationMutex_Failed)); } #if MUTEXINSTRUMENTATION // Remember the stack trace for debugging purpose _stackTrace = (new StackTrace()).ToString(); #endif Debug.Trace("Mutex", "Got mutex " + MutexDebugName); #endif // !FEATURE_PAL } #if UNUSED_CODE internal bool CheckOrFail() { #if !FEATURE_PAL // No unmanaged aspnet_isapi mutex in Coriolis if (_mutexHandle.Handle == IntPtr.Zero) throw new InvalidOperationException(SR.GetString(SR.CompilationMutex_Null)); // check the lock status for (;;) { int lockStatus = _lockStatus; if (lockStatus == -1 || _draining) throw new InvalidOperationException(SR.GetString(SR.CompilationMutex_Drained)); if (Interlocked.CompareExchange(ref _lockStatus, lockStatus+1, lockStatus) == lockStatus) break; // got the lock } Debug.Trace("Mutex", "Checking on mutex " + MutexDebugName); if (UnsafeNativeMethods.InstrumentedMutexGetLock(_mutexHandle, 0) == -1) { // failed to get the lock Debug.Trace("Mutex", "Didn't get mutex " + MutexDebugName); Interlocked.Decrement(ref _lockStatus); return false; } Debug.Trace("Mutex", "Got mutex " + MutexDebugName); return true; #else return false; #endif // !FEATURE_PAL } #endif internal /*public*/ void ReleaseMutex() { #if !FEATURE_PAL // No unmanaged aspnet_isapi mutex in Coriolis if (_mutexHandle.Handle == IntPtr.Zero) throw new InvalidOperationException(SR.GetString(SR.CompilationMutex_Null)); Debug.Trace("Mutex", "Releasing mutex " + MutexDebugName); #if MUTEXINSTRUMENTATION // Clear out the stack trace _stackTrace = null; #endif if (UnsafeNativeMethods.InstrumentedMutexReleaseLock(_mutexHandle) != 0) Interlocked.Decrement(ref _lockStatus); #endif // !FEATURE_PAL } #if UNUSED internal /*public*/ void DrainMutex() { #if !FEATURE_PAL // No unmanaged aspnet_isapi mutex in Coriolis // keep trying to set _lockStatus to -1 if it is 0 Debug.Trace("Mutex", "Starting draining mutex " + MutexDebugName); _draining = true; for (;;) { if (_lockStatus == -1) break; if (Interlocked.CompareExchange(ref _lockStatus, -1, 0) == 0) break; // got it Thread.Sleep(100); } Debug.Trace("Mutex", "Completed drained mutex " + MutexDebugName); #endif // !FEATURE_PAL } internal /*public*/ void SetState(int state) { #if !FEATURE_PAL // No unmanaged aspnet_isapi mutex in Coriolis if (_mutexHandle.Handle != IntPtr.Zero) UnsafeNativeMethods.InstrumentedMutexSetState(_mutexHandle, state); #endif // FEATURE_PAL } #endif private String MutexDebugName { get { #if DBG return (_comment != null) ? _name + " (" + _comment + ")" : _name; #else return _name; #endif } } } internal static class CompilationLock { private static CompilationMutex _mutex; static CompilationLock() { // Create the mutex (or just get it if another process created it). // Make the mutex unique per application int hashCode = ("CompilationLock" + HttpRuntime.AppDomainAppIdInternal.ToLower(CultureInfo.InvariantCulture)).GetHashCode(); _mutex = new CompilationMutex( "CL" + hashCode.ToString("x", CultureInfo.InvariantCulture), "CompilationLock for " + HttpRuntime.AppDomainAppVirtualPath); } internal static void GetLock(ref bool gotLock) { // The idea of this try/finally is to make sure that the statements are always // executed together (VSWhidbey 319154) // This code should be using a constrained execution region. try { } finally { // Always take the BuildManager lock *before* taking the mutex, to avoid possible // deadlock situations (VSWhidbey 530732) Monitor.Enter(BuildManager.TheBuildManager); _mutex.WaitOne(); gotLock = true; } } internal static void ReleaseLock() { _mutex.ReleaseMutex(); Monitor.Exit(BuildManager.TheBuildManager); } #if UNUSED internal static void DrainMutex() { _mutex.DrainMutex(); } internal static void SetMutexState(int state) { _mutex.SetState(state); } #endif } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- EditorZone.cs
- FragmentNavigationEventArgs.cs
- HostingEnvironmentSection.cs
- XComponentModel.cs
- Constraint.cs
- XmlSerializerNamespaces.cs
- assertwrapper.cs
- HttpCapabilitiesBase.cs
- FormViewRow.cs
- DotExpr.cs
- DataRelationPropertyDescriptor.cs
- TableHeaderCell.cs
- SQlBooleanStorage.cs
- Encoder.cs
- FormClosingEvent.cs
- Helpers.cs
- SqlInternalConnectionTds.cs
- AggregateNode.cs
- ApplicationSettingsBase.cs
- OdbcDataAdapter.cs
- CharacterString.cs
- ScopedMessagePartSpecification.cs
- ToolStripDropDownButton.cs
- ServiceOperationParameter.cs
- MethodRental.cs
- _IPv4Address.cs
- HtmlContainerControl.cs
- CharAnimationUsingKeyFrames.cs
- RSACryptoServiceProvider.cs
- StateChangeEvent.cs
- xsdvalidator.cs
- TextTreeRootNode.cs
- RoleGroup.cs
- WrappedIUnknown.cs
- SharedHttpTransportManager.cs
- RecommendedAsConfigurableAttribute.cs
- SynchronizationLockException.cs
- CheckBoxRenderer.cs
- FeedUtils.cs
- ResourceCollectionInfo.cs
- BookmarkCallbackWrapper.cs
- SqlExpander.cs
- SelectingProviderEventArgs.cs
- EdmValidator.cs
- Brush.cs
- PropertyChange.cs
- DesignerRegion.cs
- ReaderWriterLock.cs
- ToolStripItemTextRenderEventArgs.cs
- JobDuplex.cs
- BitmapCache.cs
- CodeCompileUnit.cs
- Activator.cs
- XamlBrushSerializer.cs
- ThreadStaticAttribute.cs
- FastEncoder.cs
- SoapFault.cs
- WebBrowserNavigatedEventHandler.cs
- DateTimeOffsetConverter.cs
- Point3D.cs
- IFlowDocumentViewer.cs
- PerformanceCounterLib.cs
- TransformPattern.cs
- BitmapEffectGeneralTransform.cs
- HttpListenerException.cs
- TailPinnedEventArgs.cs
- ThousandthOfEmRealPoints.cs
- FixedSOMPageConstructor.cs
- ConnectionPoint.cs
- PrintDialogException.cs
- TerminateDesigner.cs
- ClientScriptManager.cs
- DBSchemaTable.cs
- RegexCaptureCollection.cs
- ViewLoader.cs
- ExtendedPropertyDescriptor.cs
- AssemblyCache.cs
- TemplateNameScope.cs
- ParentQuery.cs
- WsdlContractConversionContext.cs
- InitializerFacet.cs
- SignedInfo.cs
- SelectionProviderWrapper.cs
- DetailsViewPageEventArgs.cs
- ClipboardProcessor.cs
- PhysicalOps.cs
- Util.cs
- BamlRecordReader.cs
- ListViewTableRow.cs
- OracleFactory.cs
- CookielessHelper.cs
- FileSystemEventArgs.cs
- HttpWebRequestElement.cs
- RightsManagementInformation.cs
- DbConnectionPoolIdentity.cs
- ModelFunctionTypeElement.cs
- PointAnimationBase.cs
- newinstructionaction.cs
- SocketElement.cs
- ProxyManager.cs