Esempio n. 1
0
            internal void BatchCompileDirectory(Object unused)
            {
                _thread = Thread.CurrentThread;

                try {
                    using (new HttpContextWrapper(_context)) {
                        // Set some thread data to remember that this is a batch compilation thread
                        CallContext.SetData(CallContextBatchCompilerSlotName, this);

                        // Do the impersonation
                        _context.Impersonation.Start(true /*forGlobalCode*/, false /*throwOnError*/);

                        Debug.Trace("PreservedAssemblyEntry", "Starting batch compilation of directory " + _baseVirtualDir);
                        try {
                            CodeDomBatchManager.BatchCompile(_baseVirtualDir, _context);
                        }

                        // eat exceptions and fail batch compilation silently
        #if DBG
                        catch (Exception e) {
                            if (e is ThreadAbortException)
                            {
                                Debug.Trace("PreservedAssemblyEntry", "Batch compilation of directory " + _baseVirtualDir + " was aborted.");
                            }
                            else
                            {
                                Debug.Trace("PreservedAssemblyEntry", "Batch compilation of directory " + _baseVirtualDir + " failed.");
                            }

                            Util.DumpExceptionStack(e);
                            return;
                        }
        #else
                        catch (Exception) {
                            return;
                        }
        #endif

                        finally {
                            _context.Impersonation.Stop();

                            CallContext.SetData(CallContextBatchCompilerSlotName, null);

                            if (WasAddedToBackgroundThreadsList)
                            {
                                PreservedAssemblyEntry.RemoveBackgroundBatchCompilation(this);
                            }
                        }
                    }

                    // Batching was performed successfully
                    Debug.Trace("PreservedAssemblyEntry", "Batch compilation of directory " + _baseVirtualDir + " was successful.");
                    _success = true;
                }
                catch (ThreadAbortException) {
                    // to consume thread abort exception (so that the thread pool doesn't know)
                    Thread.ResetAbort();
                }
                catch { throw; } // Prevent Exception Filter Security Issue (ASURT 122826)
                finally {
                    _thread = null;
                    _event.Set();
                }
            }
Esempio n. 2
0
        /*
         * Try batching the directory if not done yet.
         */
        private static bool BatchCompileDirectory(HttpContext context, string baseVirtualDir)
        {
            // Don't do it if batching is disabled
            if (!CompilationConfiguration.IsBatchingEnabled(context))
            {
                return(false);
            }

            if (AlreadyBatched(baseVirtualDir))
            {
                return(false);
            }

            Debug.Trace("PreservedAssemblyEntry", "Need to batch compile " + baseVirtualDir);

            // If we're already in a batch compilation tread, no need to start another one
            if (BackgroundBatchCompiler.IsBatchCompilationThread())
            {
                Debug.Trace("PreservedAssemblyEntry", "Already in batch compilation thread. No need to start a new one.");
                CodeDomBatchManager.BatchCompile(baseVirtualDir, context);
                return(true);
            }

            // Notify HttpRuntime so that it might need to abort compilation on shutdown
            HttpRuntime.NotifyThatSomeBatchCompilationStarted();

            ManualResetEvent batchEvent = new ManualResetEvent(false);

            // Pass it a Clone of the context, since it's not thread safe.  Mostly, this is important
            // for the ConfigPath (ASURT 82744)
            BackgroundBatchCompiler bbc = new BackgroundBatchCompiler(context.Clone(), baseVirtualDir, batchEvent);

            // Start the batch processing
            try {
                ThreadPool.QueueUserWorkItem(bbc.BatchCallback);
            }
            catch {
                return(false);
            }

            // Register for BeforeDoneWithSession event
            context.BeforeDoneWithSession += new EventHandler(bbc.BeforeDoneWithSessionHandler);

            // Wait a certain time for it to complete
            int timeout = 1000 * CompilationConfiguration.GetBatchTimeout(context);

            Debug.Trace("PreservedAssemblyEntry", "Waiting for " + timeout + " ms");

            if (batchEvent.WaitOne(timeout, false))
            {
                Debug.Trace("PreservedAssemblyEntry", "The background thread is done for " + baseVirtualDir + " (Success=" + bbc.Success + ")");
                return(bbc.Success);
            }

            // It didn't have time to complete.  Let it run in the background.
            Debug.Trace("PreservedAssemblyEntry", "The background thread is still going for " + baseVirtualDir);

            // Add it to the list of background compilations, in case it needs to be aborted
            AddBackgroundBatchCompilation(bbc);
            bbc.WasAddedToBackgroundThreadsList = true;

            return(false);
        }