internal static void PreloadApplicationIfNotShuttingdown (string appId, LockableAppDomainContext ac) { // If GL_STOP_LISTENING wasn't triggered, the reset is likely due to a configuration change. if (ProcessHost.DefaultHost != null && !HostingEnvironment.StopListeningWasCalled) { // Start the new app on another thread instead of hijacking the current app unloading thread ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object o) { lock (ac) { try { // NOTE: we don't know what HostingEnvironmentParameters were passed to our previous application instance // so we pass null (default for HTTP activation). We could have cached it in ApplicationContext if needed ProcessHost.DefaultHost.PreloadApplicationIfRequired(appId, null, null, ac); } catch (Exception e) { ProcessHost.DefaultHost.ReportApplicationPreloadFailureWithAssert( ac.PreloadContext, HResults.E_FAIL, Misc.FormatExceptionMessage( e, new string[] { SR.GetString(SR.Failure_Preload_Application_Initialization)})); } } })); } }
internal LockableAppDomainContext GetLockableAppDomainContext(string appId) { lock (this) { LockableAppDomainContext context; if (!this._appDomains.TryGetValue(appId, out context)) { context = new LockableAppDomainContext(); this._appDomains.Add(appId, context); } return context; } }
// New for Dev10. // creates a new AppDomain, preloads and calls user code in it internal void PreloadApplicationIfRequired( string appId, IApplicationHost appHostParameter, HostingEnvironmentParameters hostingParameters, LockableAppDomainContext ac) { // NOTE1: Must never be called under lock (_appManager) // NOTE2: Must always be called under lock (ac) // We only need to preload if auto start is enabled and we have not already preloaded (i.e. HostingEnvironment doesn't exist) if (_preloadUtil == null || ac.PreloadContext == null || ac.HostEnv != null) { return; } // Get and verify the preload parameters string preloadObjTypeName; string[] paramsForStartupObj; bool stillEnabled; GetApplicationPreloadInfoWithAssert(ac.PreloadContext, out stillEnabled, out preloadObjTypeName, out paramsForStartupObj); // Dev10: 782385 ASP.NET autostart implementation should be tolerant of empty string for the provider type if (!stillEnabled || String.IsNullOrEmpty(preloadObjTypeName)) { return; } // Ready to load the App Domain if (_preloadingThrottle != null) { // Throttle the number of simultaneously created appdomains _preloadingThrottle.WaitOne(); } try { // Create the app-host and start a new App Domain IApplicationHost appHost = (appHostParameter == null) ? CreateAppHost(appId, null) : appHostParameter; // call app manager to create the PreloadHost PreloadHost preloadHostObj = (PreloadHost)_appManager.CreateObjectInternal( appId, typeof(PreloadHost), appHost, true /*failIfExists*/, hostingParameters); // Dev10 858421: File sharing violations on config files cause unnecessary process shutdown in autostart mode // // There are race conditions between whoever modifies the config files // and the application config system that reads from the config files // These file sharing violation lead to random application initialization failures // Service auto-start mode is more vulnerable to these sharing violations because // it starts a new app domain as soon as the file change notification is received // and when an error occurs IIS recycles the whole app pool rather than a particular app // // In most cases that we see in stress the inner most exception is System.IO.IOException // so if we see this exception we will give it another try before // reporting the errors to IIS and recycling the process // // Check for I/O exceptions during initialization and retry one time Exception appInitEx = preloadHostObj.InitializationException; if (GetInnerMostException(appInitEx) is IOException) { try { // prevent ApplicationManager.HostingEnvironmentShutdownInitiated from attempting to preload again ac.RetryingPreload = true; // shutdown old hosting environment ac.HostEnv.InitiateShutdownInternal(); } finally { ac.RetryingPreload = false; } // Create the app-host and start a new App Domain appHost = (appHostParameter == null) ? CreateAppHost(appId, null) : appHostParameter; // call app manager to create the PreloadHost preloadHostObj = (PreloadHost)_appManager.CreateObjectInternal( appId, typeof(PreloadHost), appHost, true /*failIfExists*/, hostingParameters); appInitEx = preloadHostObj.InitializationException; } // Check again for initialization exception and tell IIS to recycle the process if (appInitEx != null) { ReportApplicationPreloadFailureWithAssert( ac.PreloadContext, HResults.E_FAIL, Misc.FormatExceptionMessage( appInitEx, new string[] { SR.GetString(SR.Failure_Preload_Application_Initialization)} )); // we must throw if preload fails because we cannot allow the normal // startup path to continue and attempt to create a HostingEnvironment throw appInitEx; } // Call preload code in the App Domain try { preloadHostObj.CreateIProcessHostPreloadClientInstanceAndCallPreload(preloadObjTypeName, paramsForStartupObj); } catch (Exception e) { // report errors ReportApplicationPreloadFailureWithAssert( ac.PreloadContext, HResults.E_FAIL, Misc.FormatExceptionMessage( e, new string[] { SR.GetString(SR.Failure_Calling_Preload_Provider)} ).ToString()); throw; } } finally { if (_preloadingThrottle != null) { _preloadingThrottle.Release(); } } }
internal void PreloadApplicationIfRequired(string appId, IApplicationHost appHostParameter, HostingEnvironmentParameters hostingParameters, LockableAppDomainContext ac) { if (((this._preloadUtil != null) && (ac.PreloadContext != null)) && (ac.HostEnv == null)) { string str; string[] strArray; bool flag; this.GetApplicationPreloadInfoWithAssert(ac.PreloadContext, out flag, out str, out strArray); if (flag && !string.IsNullOrEmpty(str)) { if (this._preloadingThrottle != null) { this._preloadingThrottle.WaitOne(); } try { IApplicationHost appHost = (appHostParameter == null) ? this.CreateAppHost(appId, null) : appHostParameter; PreloadHost host2 = (PreloadHost)this._appManager.CreateObjectInternal(appId, typeof(PreloadHost), appHost, true, hostingParameters); Exception initializationException = host2.InitializationException; if (GetInnerMostException(initializationException) is IOException) { try { ac.RetryingPreload = true; ac.HostEnv.InitiateShutdownInternal(); } finally { ac.RetryingPreload = false; } appHost = (appHostParameter == null) ? this.CreateAppHost(appId, null) : appHostParameter; host2 = (PreloadHost)this._appManager.CreateObjectInternal(appId, typeof(PreloadHost), appHost, true, hostingParameters); initializationException = host2.InitializationException; } if (initializationException != null) { this.ReportApplicationPreloadFailureWithAssert(ac.PreloadContext, -2147467259, Misc.FormatExceptionMessage(initializationException, new string[] { System.Web.SR.GetString("Failure_Preload_Application_Initialization") })); throw initializationException; } try { host2.CreateIProcessHostPreloadClientInstanceAndCallPreload(str, strArray); } catch (Exception exception2) { this.ReportApplicationPreloadFailureWithAssert(ac.PreloadContext, -2147467259, Misc.FormatExceptionMessage(exception2, new string[] { System.Web.SR.GetString("Failure_Calling_Preload_Provider") }).ToString()); throw; } } finally { if (this._preloadingThrottle != null) { this._preloadingThrottle.Release(); } } } } }