Acts as countdown timer, used to measure elapsed time over a sync operation.
internal override TimerThread.Timer CreateTimer(TimerThread.Callback callback, object context) { TimerThread.TimerNode node = new TimerThread.TimerNode(callback, context, base.Duration, this.m_Timers); bool flag = false; lock (this.m_Timers) { if (this.m_Timers.Next == this.m_Timers) { if (this.m_ThisHandle == IntPtr.Zero) { this.m_ThisHandle = (IntPtr)GCHandle.Alloc(this); } flag = true; } node.Next = this.m_Timers; node.Prev = this.m_Timers.Prev; this.m_Timers.Prev.Next = node; this.m_Timers.Prev = node; } if (flag) { TimerThread.Prod(); } return(node); }
internal ServicePoint(Uri address, TimerThread.Queue defaultIdlingQueue, int defaultConnectionLimit, string lookupString, bool userChangedLimit, bool proxyServicePoint) { this.m_HostName = string.Empty; this.m_ProxyServicePoint = proxyServicePoint; this.m_Address = address; this.m_ConnectionName = address.Scheme; this.m_Host = address.DnsSafeHost; this.m_Port = address.Port; this.m_IdlingQueue = defaultIdlingQueue; this.m_ConnectionLimit = defaultConnectionLimit; this.m_HostLoopbackGuess = TriState.Unspecified; this.m_LookupString = lookupString; this.m_UserChangedLimit = userChangedLimit; this.m_UseNagleAlgorithm = ServicePointManager.UseNagleAlgorithm; this.m_Expect100Continue = ServicePointManager.Expect100Continue; this.m_ConnectionGroupList = new Hashtable(10); this.m_ConnectionLeaseTimeout = -1; this.m_ReceiveBufferSize = -1; this.m_UseTcpKeepAlive = ServicePointManager.s_UseTcpKeepAlive; this.m_TcpKeepAliveTime = ServicePointManager.s_TcpKeepAliveTime; this.m_TcpKeepAliveInterval = ServicePointManager.s_TcpKeepAliveInterval; this.m_Understands100Continue = true; this.m_HttpBehaviour = System.Net.HttpBehaviour.Unknown; this.m_IdleSince = DateTime.Now; this.m_ExpiringTimer = this.m_IdlingQueue.CreateTimer(ServicePointManager.IdleServicePointTimeoutDelegate, this); }
internal void Close() { site.Close(); // Can't call AppDomain.Unload() from a user thread. TimerThread.GetOrCreateQueue(0).CreateTimer(new TimerThread.Callback(CloseAppDomainCallback), appDomainIndex); GC.SuppressFinalize(this); }
internal ConnectionPool(System.Net.ServicePoint servicePoint, int maxPoolSize, int minPoolSize, int idleTimeout, CreateConnectionDelegate createConnectionCallback) { this.m_CreateConnectionCallback = createConnectionCallback; this.m_MaxPoolSize = maxPoolSize; this.m_MinPoolSize = minPoolSize; this.m_ServicePoint = servicePoint; this.Initialize(); if (idleTimeout > 0) { this.m_CleanupQueue = TimerThread.GetOrCreateQueue((idleTimeout == 1) ? 1 : (idleTimeout / 2)); this.m_CleanupQueue.CreateTimer(s_CleanupCallback, this); } }
internal bool Fire() { if (this.m_TimerState == TimerState.Ready) { int tickCount = Environment.TickCount; if (TimerThread.IsTickBetween(base.StartTime, base.Expiration, tickCount)) { return(false); } bool flag = false; lock (this.m_QueueLock) { if (this.m_TimerState == TimerState.Ready) { this.m_TimerState = TimerState.Fired; this.Next.Prev = this.Prev; this.Prev.Next = this.Next; this.Next = null; this.Prev = null; flag = this.m_Callback != null; } } if (flag) { try { TimerThread.Callback callback = this.m_Callback; object context = this.m_Context; this.m_Callback = null; this.m_Context = null; callback(this, tickCount, context); } catch (Exception exception) { if (NclUtilities.IsFatal(exception)) { throw; } if (Logging.On) { Logging.PrintError(Logging.Web, "TimerThreadTimer#" + base.StartTime.ToString(NumberFormatInfo.InvariantInfo) + "::Fire() - " + SR.GetString("net_log_exception_in_callback", new object[] { exception })); } } } } return(true); }
/// <summary> /// <para>Constructor - binds pool with a servicePoint and sets up a cleanup Timer to nuke Idle Connections</para> /// </summary> internal ConnectionPool(ServicePoint servicePoint, int maxPoolSize, int minPoolSize, int idleTimeout, CreateConnectionDelegate createConnectionCallback) : base() { m_State = State.Initializing; m_CreateConnectionCallback = createConnectionCallback; m_MaxPoolSize = maxPoolSize; m_MinPoolSize = minPoolSize; m_ServicePoint = servicePoint; Initialize(); if (idleTimeout > 0) { m_CleanupQueue = TimerThread.GetOrCreateQueue(idleTimeout / 2); m_CleanupQueue.CreateTimer(s_CleanupCallback, this); } }
/// <summary> /// <para>Creates new timers. This method is thread-safe.</para> /// </summary> internal override Timer CreateTimer(Callback callback, object context) { TimerNode timer = new TimerNode(callback, context, Duration, _timers); // Add this on the tail. (Actually, one before the tail - _timers is the sentinel tail.) bool needProd = false; lock (_timers) { if (!(_timers.Prev.Next == _timers)) { if (GlobalLog.IsEnabled) { GlobalLog.AssertFormat("TimerThread#{0}::CreateTimer()|Tail corruption.", Thread.CurrentThread.ManagedThreadId.ToString()); } Debug.Fail(string.Format("TimerThread#{0}::CreateTimer()|Tail corruption.", Thread.CurrentThread.ManagedThreadId.ToString())); } // If this is the first timer in the list, we need to create a queue handle and prod the timer thread. if (_timers.Next == _timers) { if (_thisHandle == IntPtr.Zero) { _thisHandle = (IntPtr)GCHandle.Alloc(this); } needProd = true; } timer.Next = _timers; timer.Prev = _timers.Prev; _timers.Prev.Next = timer; _timers.Prev = timer; } // If, after we add the new tail, there is a chance that the tail is the next // node to be processed, we need to wake up the timer thread. if (needProd) { TimerThread.Prod(); } return(timer); }
internal ServicePoint(string host, int port, TimerThread.Queue defaultIdlingQueue, int defaultConnectionLimit, string lookupString, bool userChangedLimit, bool proxyServicePoint) { this.m_HostName = string.Empty; this.m_ProxyServicePoint = proxyServicePoint; this.m_ConnectionName = "ByHost:" + host + ":" + port.ToString(CultureInfo.InvariantCulture); this.m_IdlingQueue = defaultIdlingQueue; this.m_ConnectionLimit = defaultConnectionLimit; this.m_HostLoopbackGuess = TriState.Unspecified; this.m_LookupString = lookupString; this.m_UserChangedLimit = userChangedLimit; this.m_ConnectionGroupList = new Hashtable(10); this.m_ConnectionLeaseTimeout = -1; this.m_ReceiveBufferSize = -1; this.m_Host = host; this.m_Port = port; this.m_HostMode = true; this.m_IdleSince = DateTime.Now; this.m_ExpiringTimer = this.m_IdlingQueue.CreateTimer(ServicePointManager.IdleServicePointTimeoutDelegate, this); }
/// <summary> /// <para>Constructor - binds pool with a servicePoint and sets up a cleanup Timer to remove Idle Connections</para> /// </summary> internal ConnectionPool(ServicePoint servicePoint, int maxPoolSize, int minPoolSize, int idleTimeout, CreateConnectionDelegate createConnectionCallback) : base() { m_State = State.Initializing; m_CreateConnectionCallback = createConnectionCallback; m_MaxPoolSize = maxPoolSize; m_MinPoolSize = minPoolSize; m_ServicePoint = servicePoint; Initialize(); if (idleTimeout > 0) { // special case: if the timeout value is 1 then the timer thread should have a duration // of 1 to avoid having the timer callback run constantly m_CleanupQueue = TimerThread.GetOrCreateQueue(idleTimeout == 1 ? 1 : (idleTimeout / 2)); m_CleanupQueue.CreateTimer(s_CleanupCallback, this); } }
/// <summary> /// <para>Creates new timers. This method is thread-safe.</para> /// </summary> internal override Timer CreateTimer(Callback callback, object context) { TimerNode timer = new TimerNode(callback, context, Duration, _timers); // Add this on the tail. (Actually, one before the tail - _timers is the sentinel tail.) bool needProd = false; lock (_timers) { if (!(_timers.Prev.Next == _timers)) { NetEventSource.Fail(this, $"Tail corruption."); } // If this is the first timer in the list, we need to create a queue handle and prod the timer thread. if (_timers.Next == _timers) { if (_thisHandle == IntPtr.Zero) { _thisHandle = (IntPtr)GCHandle.Alloc(this); } needProd = true; } timer.Next = _timers; timer.Prev = _timers.Prev; _timers.Prev.Next = timer; _timers.Prev = timer; } // If, after we add the new tail, there is a chance that the tail is the next // node to be processed, we need to wake up the timer thread. if (needProd) { TimerThread.Prod(); } return(timer); }
internal abstract TimerThread.Timer CreateTimer(TimerThread.Callback callback, object context);
/// <summary> /// <para>Because this is called from the timer thread, neither it nor any methods it calls can call user code.</para> /// </summary> private void TimerCallback(TimerThread.Timer timer, int timeNoticed, object context) { GlobalLog.Print("FtpWebRequest#" + ValidationHelper.HashString(this) + "::TimerCallback"); FtpControlStream connection = m_Connection; if (connection != null) { GlobalLog.Print("FtpWebRequest#" + ValidationHelper.HashString(this) + "::TimerCallback aborting connection"); connection.AbortConnect(); } }
private static void InterruptCallback(TimerThread.Timer timer, int timeNoticed, object context) { AutoWebProxyScriptWrapper pThis = (AutoWebProxyScriptWrapper)context; GlobalLog.Print("AutoWebProxyScriptWrapper#" + ValidationHelper.HashString(pThis) + "::InterruptCallback()"); if (!object.ReferenceEquals(timer, pThis.activeTimer)) { GlobalLog.Print("AutoWebProxyScriptWrapper#" + ValidationHelper.HashString(pThis) + "::InterruptCallback() Spurious - returning."); return; } EXCEPINFO exceptionInfo; try { pThis.jscript.InterruptScriptThread(pThis.interruptThreadId, out exceptionInfo, 0); } catch (Exception ex) { if (NclUtilities.IsFatal(ex)) throw; GlobalLog.Print("AutoWebProxyScriptWrapper#" + ValidationHelper.HashString(pThis) + "::InterruptCallback() InterruptScriptThread() threw:" + ValidationHelper.ToString(ex)); } catch { GlobalLog.Print("AutoWebProxyScriptWrapper#" + ValidationHelper.HashString(pThis) + "::InterruptCallback() InterruptScriptThread() threw: Non-CLS Compliant Exception"); } }
private static void IdleServicePointTimeoutCallback(TimerThread.Timer timer, int timeNoticed, object context) { ServicePoint servicePoint = (ServicePoint) context; if (Logging.On) Logging.PrintInfo(Logging.Web, SR.GetString(SR.net_log_closed_idle, "ServicePoint", servicePoint.GetHashCode())); lock (s_ServicePointTable) { s_ServicePointTable.Remove(servicePoint.LookupString); } servicePoint.ReleaseAllConnectionGroups(); }
private static void CancelErrorCallbackWrapper(TimerThread.Timer timer, int timeNoticed, object context) { ((ConnectionPool) context).CancelErrorCallback(); }
private static void CleanupCallbackWrapper(TimerThread.Timer timer, int timeNoticed, object context) { ConnectionPool pThis = (ConnectionPool) context; try { pThis.CleanupCallback(); } finally { pThis.m_CleanupQueue.CreateTimer(s_CleanupCallback, context); } }
internal void Close() { this.site.Close(); TimerThread.GetOrCreateQueue(0).CreateTimer(new TimerThread.Callback(AutoWebProxyScriptWrapper.CloseAppDomainCallback), this.appDomainIndex); GC.SuppressFinalize(this); }
private void CreateAppDomain() { bool lockTaken = false; RuntimeHelpers.PrepareConstrainedRegions(); try { Monitor.Enter(s_AppDomains.SyncRoot, ref lockTaken); if (s_CleanedUp) { throw new InvalidOperationException(SR.GetString("net_cant_perform_during_shutdown")); } if (s_AppDomainInfo == null) { s_AppDomainInfo = new AppDomainSetup(); s_AppDomainInfo.DisallowBindingRedirects = true; s_AppDomainInfo.DisallowCodeDownload = true; NamedPermissionSet permSet = new NamedPermissionSet("__WebProxySandbox", PermissionState.None); permSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution)); ApplicationTrust trust = new ApplicationTrust { DefaultGrantSet = new PolicyStatement(permSet) }; s_AppDomainInfo.ApplicationTrust = trust; s_AppDomainInfo.ApplicationBase = Environment.SystemDirectory; } AppDomain context = s_ExcessAppDomain; if (context != null) { TimerThread.GetOrCreateQueue(0).CreateTimer(new TimerThread.Callback(AutoWebProxyScriptWrapper.CloseAppDomainCallback), context); throw new InvalidOperationException(SR.GetString("net_cant_create_environment")); } this.appDomainIndex = s_NextAppDomainIndex++; try { } finally { PermissionSet grantSet = new PermissionSet(PermissionState.None); grantSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution)); s_ExcessAppDomain = AppDomain.CreateDomain("WebProxyScript", null, s_AppDomainInfo, grantSet, null); try { s_AppDomains.Add(this.appDomainIndex, s_ExcessAppDomain); this.scriptDomain = s_ExcessAppDomain; } finally { if (object.ReferenceEquals(this.scriptDomain, s_ExcessAppDomain)) { s_ExcessAppDomain = null; } else { try { s_AppDomains.Remove(this.appDomainIndex); } finally { TimerThread.GetOrCreateQueue(0).CreateTimer(new TimerThread.Callback(AutoWebProxyScriptWrapper.CloseAppDomainCallback), s_ExcessAppDomain); } } } } } finally { if (lockTaken) { Monitor.Exit(s_AppDomains.SyncRoot); } } }
internal override TimerThread.Timer CreateTimer(TimerThread.Callback callback, object context) { TimerThread.TimerNode node = new TimerThread.TimerNode(callback, context, base.Duration, this.m_Timers); bool flag = false; lock (this.m_Timers) { if (this.m_Timers.Next == this.m_Timers) { if (this.m_ThisHandle == IntPtr.Zero) { this.m_ThisHandle = (IntPtr) GCHandle.Alloc(this); } flag = true; } node.Next = this.m_Timers; node.Prev = this.m_Timers.Prev; this.m_Timers.Prev.Next = node; this.m_Timers.Prev = node; } if (flag) { TimerThread.Prod(); } return node; }
internal TimerNode(TimerThread.Callback callback, object context, int durationMilliseconds, object queueLock) : base(durationMilliseconds) { if (callback != null) { this.m_Callback = callback; this.m_Context = context; } this.m_TimerState = TimerState.Ready; this.m_QueueLock = queueLock; }
// TimeoutCallback - Called by the TimerThread to abort a request. This just posts ThreadPool work item - Abort() does too // much to be done on the timer thread (timer thread should never block or call user code). private static void TimeoutCallback(TimerThread.Timer timer, int timeNoticed, object context) { ThreadPool.UnsafeQueueUserWorkItem(s_AbortWrapper, context); }
// This can never call into user code or block, because it's called by the TimerThread. private static void ContinueTimeoutCallback(TimerThread.Timer timer, int timeNoticed, object context) { GlobalLog.Enter("HttpWebRequest#" + ValidationHelper.HashString(context) + "::ContinueTimeoutCallback"); GlobalLog.ThreadContract(ThreadKinds.Unknown, ThreadKinds.SafeSources | ThreadKinds.Timer, "HttpWebRequest#" + ValidationHelper.HashString(context) + "::ContinueTimeoutCallback"); HttpWebRequest thisHttpWebRequest = (HttpWebRequest) context; if (thisHttpWebRequest.HttpWriteMode == HttpWriteMode.None) { GlobalLog.Assert("HttpWebRequest#" + ValidationHelper.HashString(thisHttpWebRequest) + "::CompleteContinueGate()", "Not a POST type request, must not come here."); return; } // Complete the 100 Continue gate. If this completes it then it is safe to re/upload the data. // Otherwise we already received a continue/response. if (!(thisHttpWebRequest.FinishContinueWait() && thisHttpWebRequest.CompleteContinueGate())) { return; } // // We have to put it on a threadpool thread since it may call user code. This is not // a critical path for perf. ThreadPool.UnsafeQueueUserWorkItem(s_EndWriteHeaders_Part2Callback, thisHttpWebRequest); GlobalLog.Leave("HttpWebRequest#" + ValidationHelper.HashString(thisHttpWebRequest) + "::ContinueTimeoutCallback"); }
private static void IdleServicePointTimeoutCallback(TimerThread.Timer timer, int timeNoticed, object context) { ServicePoint servicePoint = (ServicePoint) context; lock (s_ServicePointTable) { s_ServicePointTable.Remove(servicePoint.LookupString); } servicePoint.ReleaseAllConnectionGroups(); }
private void CreateAppDomain() { // Locking s_AppDomains must happen in a CER so we don't orphan a lock that gets taken by AppDomain.DomainUnload. bool lockHeld = false; RuntimeHelpers.PrepareConstrainedRegions(); try { Monitor.Enter(s_AppDomains.SyncRoot, ref lockHeld); if (s_CleanedUp) { throw new InvalidOperationException(SR.GetString(SR.net_cant_perform_during_shutdown)); } // Create singleton. if (s_AppDomainInfo == null) { s_AppDomainInfo = new AppDomainSetup(); s_AppDomainInfo.DisallowBindingRedirects = true; s_AppDomainInfo.DisallowCodeDownload = true; NamedPermissionSet perms = new NamedPermissionSet("__WebProxySandbox", PermissionState.None); perms.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution)); ApplicationTrust trust = new ApplicationTrust(); trust.DefaultGrantSet = new PolicyStatement(perms); s_AppDomainInfo.ApplicationTrust = trust; s_AppDomainInfo.ApplicationBase = Environment.SystemDirectory; } // If something's already in s_ExcessAppDomain, try to dislodge it again. AppDomain excessAppDomain = s_ExcessAppDomain; if (excessAppDomain != null) { TimerThread.GetOrCreateQueue(0).CreateTimer(new TimerThread.Callback(CloseAppDomainCallback), excessAppDomain); throw new InvalidOperationException(SR.GetString(SR.net_cant_create_environment)); } appDomainIndex = s_NextAppDomainIndex++; try { } finally { PermissionSet permissionSet = new PermissionSet(PermissionState.None); permissionSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution)); // s_ExcessAppDomain = AppDomain.CreateDomain(c_appDomainName, null, s_AppDomainInfo, permissionSet, null); try { s_AppDomains.Add(appDomainIndex, s_ExcessAppDomain); // This indicates to the finally and the finalizer that everything succeeded. scriptDomain = s_ExcessAppDomain; } finally { // ReferenceEquals has a ReliabilityContract. if (object.ReferenceEquals(scriptDomain, s_ExcessAppDomain)) { s_ExcessAppDomain = null; } else { // Something failed. Leave the domain in s_ExcessAppDomain until we can get rid of it. No // more AppDomains can be created until we do. In the mean time, keep attempting to get the // TimerThread to remove it. Also, might as well remove it from the hash if it made it in. try { s_AppDomains.Remove(appDomainIndex); } finally { // Can't call AppDomain.Unload from a user thread (or in a lock). TimerThread.GetOrCreateQueue(0).CreateTimer(new TimerThread.Callback(CloseAppDomainCallback), s_ExcessAppDomain); } } } } } finally { if (lockHeld) { Monitor.Exit(s_AppDomains.SyncRoot); } } }
// Downloads and compiles the script from a given Uri. // This code can be called by config for a downloaded control, we need to assert. // This code is called holding the lock. private AutoWebProxyState DownloadAndCompile(Uri location) { GlobalLog.Print("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::DownloadAndCompile() location:" + ValidationHelper.ToString(location)); AutoWebProxyState newState = AutoWebProxyState.DownloadFailure; WebResponse response = null; TimerThread.Timer timer = null; AutoWebProxyScriptWrapper newScriptInstance = null; // Can't assert this in declarative form (DCR?). This Assert() is needed to be able to create the request to download the proxy script. ExceptionHelper.WebPermissionUnrestricted.Assert(); try { lock (lockObject) { if (aborted) { throw new WebException(NetRes.GetWebStatusString("net_requestaborted", WebExceptionStatus.RequestCanceled), WebExceptionStatus.RequestCanceled); } request = WebRequest.Create(location); } request.Timeout = Timeout.Infinite; request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.Default); request.ConnectionGroupName = "__WebProxyScript"; // We have an opportunity here, if caching is disabled AppDomain-wide, to override it with a // custom, trivial cache-provider to get a similar semantic. // // We also want to have a backup caching key in the case when IE has locked an expired script response // if (request.CacheProtocol != null) { GlobalLog.Print("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::DownloadAndCompile() Using backup caching."); request.CacheProtocol = new RequestCacheProtocol(backupCache, request.CacheProtocol.Validator); } HttpWebRequest httpWebRequest = request as HttpWebRequest; if (httpWebRequest != null) { httpWebRequest.Accept = "*/*"; httpWebRequest.UserAgent = this.GetType().FullName + "/" + Environment.Version; httpWebRequest.KeepAlive = false; httpWebRequest.Pipelined = false; httpWebRequest.InternalConnectionGroup = true; } else { FtpWebRequest ftpWebRequest = request as FtpWebRequest; if (ftpWebRequest != null) { ftpWebRequest.KeepAlive = false; } } // Use no proxy, default cache - initiate the download. request.Proxy = null; request.Credentials = Engine.Credentials; // Use our own timeout timer so that it can encompass the whole request, not just the headers. if (timerQueue == null) { timerQueue = TimerThread.GetOrCreateQueue(SettingsSectionInternal.Section.DownloadTimeout); } timer = timerQueue.CreateTimer(timerCallback, request); response = request.GetResponse(); // Check Last Modified. DateTime lastModified = DateTime.MinValue; HttpWebResponse httpResponse = response as HttpWebResponse; if (httpResponse != null) { lastModified = httpResponse.LastModified; } else { FtpWebResponse ftpResponse = response as FtpWebResponse; if (ftpResponse != null) { lastModified = ftpResponse.LastModified; } } GlobalLog.Print("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::DownloadAndCompile() lastModified:" + lastModified.ToString() + " (script):" + (scriptInstance == null ? "(null)" : scriptInstance.LastModified.ToString())); if (scriptInstance != null && lastModified != DateTime.MinValue && scriptInstance.LastModified == lastModified) { newScriptInstance = scriptInstance; newState = AutoWebProxyState.Completed; } else { string scriptBody = null; byte[] scriptBuffer = null; using (Stream responseStream = response.GetResponseStream()) { SingleItemRequestCache.ReadOnlyStream ros = responseStream as SingleItemRequestCache.ReadOnlyStream; if (ros != null) { scriptBuffer = ros.Buffer; } if (scriptInstance != null && scriptBuffer != null && scriptBuffer == scriptInstance.Buffer) { scriptInstance.LastModified = lastModified; newScriptInstance = scriptInstance; newState = AutoWebProxyState.Completed; GlobalLog.Print("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::DownloadAndCompile() Buffer matched - reusing Engine."); } else { using (StreamReader streamReader = new StreamReader(responseStream)) { scriptBody = streamReader.ReadToEnd(); } } } WebResponse tempResponse = response; response = null; tempResponse.Close(); timer.Cancel(); timer = null; if (newState != AutoWebProxyState.Completed) { GlobalLog.Print("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::DownloadAndCompile() IsFromCache:" + tempResponse.IsFromCache.ToString() + " scriptInstance:" + ValidationHelper.HashString(scriptInstance)); if (scriptInstance != null && scriptBody == scriptInstance.ScriptBody) { GlobalLog.Print("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::DownloadAndCompile() Script matched - using existing Engine."); scriptInstance.LastModified = lastModified; if (scriptBuffer != null) { scriptInstance.Buffer = scriptBuffer; } newScriptInstance = scriptInstance; newState = AutoWebProxyState.Completed; } else { GlobalLog.Print("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::DownloadAndCompile() Creating AutoWebProxyScriptWrapper."); newScriptInstance = new AutoWebProxyScriptWrapper(); newScriptInstance.LastModified = lastModified; if (newScriptInstance.Compile(location, scriptBody, scriptBuffer)) { newState = AutoWebProxyState.Completed; } else { newState = AutoWebProxyState.CompilationFailure; } } } } } catch (Exception exception) { if (Logging.On) { Logging.PrintWarning(Logging.Web, SR.GetString(SR.net_log_proxy_script_download_compile_error, exception)); } GlobalLog.Print("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::DownloadAndCompile() Download() threw:" + ValidationHelper.ToString(exception)); } finally { if (timer != null) { timer.Cancel(); } // try { if (response != null) { response.Close(); } } finally { WebPermission.RevertAssert(); // The request is not needed anymore. Set it to null, so if Abort() gets called, // after this point, it will result in a no-op. request = null; } } if ((newState == AutoWebProxyState.Completed) && (scriptInstance != newScriptInstance)) { if (scriptInstance != null) { scriptInstance.Close(); } scriptInstance = newScriptInstance; } GlobalLog.Print("NetWebProxyFinder#" + ValidationHelper.HashString(this) + "::DownloadAndCompile() retuning newState:" + ValidationHelper.ToString(newState)); return(newState); }
// This can never call into user code or block, because it's called by the TimerThread. private static void ContinueTimeoutCallback(TimerThread.Timer timer, int timeNoticed, object context) { GlobalLog.Enter("HttpWebRequest#" + ValidationHelper.HashString(context) + "::ContinueTimeoutCallback"); GlobalLog.ThreadContract(ThreadKinds.Unknown, ThreadKinds.SafeSources | ThreadKinds.Timer, "HttpWebRequest#" + ValidationHelper.HashString(context) + "::ContinueTimeoutCallback"); HttpWebRequest thisHttpWebRequest = (HttpWebRequest) context; if (thisHttpWebRequest.HttpWriteMode == HttpWriteMode.None) { GlobalLog.Assert("HttpWebRequest#" + ValidationHelper.HashString(thisHttpWebRequest) + "::CompleteContinueGate()", "Not a POST type request, must not come here."); return; } // Complete the 100 Continue gate. If this completes it, clean up the timer. if (thisHttpWebRequest.CompleteContinueGate()) { GlobalLog.Assert(thisHttpWebRequest.m_ContinueTimer == timer, "HttpWebRequest#{0}::ContinueTimeoutCallback|Timers don't match.", ValidationHelper.HashString(thisHttpWebRequest)); thisHttpWebRequest.m_ContinueTimer = null; } // Always call this. Otherwise the timer should have been successfully cancelled. // // We have to put it on a threadpool thread since it may call user code. This is not // a critical path for perf. ThreadPool.UnsafeQueueUserWorkItem(s_EndWriteHeaders_Part2Callback, thisHttpWebRequest); GlobalLog.Leave("HttpWebRequest#" + ValidationHelper.HashString(thisHttpWebRequest) + "::ContinueTimeoutCallback"); }
private BaseWebProxyFinder.AutoWebProxyState DownloadAndCompile(Uri location) { BaseWebProxyFinder.AutoWebProxyState downloadFailure = BaseWebProxyFinder.AutoWebProxyState.DownloadFailure; WebResponse response = null; TimerThread.Timer timer = null; AutoWebProxyScriptWrapper scriptInstance = null; ExceptionHelper.WebPermissionUnrestricted.Assert(); try { lock (this.lockObject) { if (this.aborted) { throw new WebException(NetRes.GetWebStatusString("net_requestaborted", WebExceptionStatus.RequestCanceled), WebExceptionStatus.RequestCanceled); } this.request = WebRequest.Create(location); } this.request.Timeout = -1; this.request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.Default); this.request.ConnectionGroupName = "__WebProxyScript"; if (this.request.CacheProtocol != null) { this.request.CacheProtocol = new RequestCacheProtocol(this.backupCache, this.request.CacheProtocol.Validator); } HttpWebRequest request = this.request as HttpWebRequest; if (request != null) { request.Accept = "*/*"; request.UserAgent = base.GetType().FullName + "/" + Environment.Version; request.KeepAlive = false; request.Pipelined = false; request.InternalConnectionGroup = true; } else { FtpWebRequest request2 = this.request as FtpWebRequest; if (request2 != null) { request2.KeepAlive = false; } } this.request.Proxy = null; this.request.Credentials = base.Engine.Credentials; if (timerQueue == null) { timerQueue = TimerThread.GetOrCreateQueue(SettingsSectionInternal.Section.DownloadTimeout); } timer = timerQueue.CreateTimer(timerCallback, this.request); response = this.request.GetResponse(); DateTime minValue = DateTime.MinValue; HttpWebResponse response2 = response as HttpWebResponse; if (response2 != null) { minValue = response2.LastModified; } else { FtpWebResponse response3 = response as FtpWebResponse; if (response3 != null) { minValue = response3.LastModified; } } if (((this.scriptInstance != null) && (minValue != DateTime.MinValue)) && (this.scriptInstance.LastModified == minValue)) { scriptInstance = this.scriptInstance; downloadFailure = BaseWebProxyFinder.AutoWebProxyState.Completed; } else { string scriptBody = null; byte[] buffer = null; using (Stream stream = response.GetResponseStream()) { SingleItemRequestCache.ReadOnlyStream stream2 = stream as SingleItemRequestCache.ReadOnlyStream; if (stream2 != null) { buffer = stream2.Buffer; } if (((this.scriptInstance != null) && (buffer != null)) && (buffer == this.scriptInstance.Buffer)) { this.scriptInstance.LastModified = minValue; scriptInstance = this.scriptInstance; downloadFailure = BaseWebProxyFinder.AutoWebProxyState.Completed; } else { using (StreamReader reader = new StreamReader(stream)) { scriptBody = reader.ReadToEnd(); } } } WebResponse response4 = response; response = null; response4.Close(); timer.Cancel(); timer = null; if (downloadFailure != BaseWebProxyFinder.AutoWebProxyState.Completed) { if ((this.scriptInstance != null) && (scriptBody == this.scriptInstance.ScriptBody)) { this.scriptInstance.LastModified = minValue; if (buffer != null) { this.scriptInstance.Buffer = buffer; } scriptInstance = this.scriptInstance; downloadFailure = BaseWebProxyFinder.AutoWebProxyState.Completed; } else { scriptInstance = new AutoWebProxyScriptWrapper { LastModified = minValue }; if (scriptInstance.Compile(location, scriptBody, buffer)) { downloadFailure = BaseWebProxyFinder.AutoWebProxyState.Completed; } else { downloadFailure = BaseWebProxyFinder.AutoWebProxyState.CompilationFailure; } } } } } catch (Exception exception) { if (Logging.On) { Logging.PrintWarning(Logging.Web, SR.GetString("net_log_proxy_script_download_compile_error", new object[] { exception })); } } finally { if (timer != null) { timer.Cancel(); } try { if (response != null) { response.Close(); } } finally { CodeAccessPermission.RevertAssert(); this.request = null; } } if ((downloadFailure == BaseWebProxyFinder.AutoWebProxyState.Completed) && (this.scriptInstance != scriptInstance)) { if (this.scriptInstance != null) { this.scriptInstance.Close(); } this.scriptInstance = scriptInstance; } return(downloadFailure); }
private static void CloseAppDomainCallback(TimerThread.Timer timer, int timeNoticed, object context) { try { AppDomain domain = context as AppDomain; if (domain == null) { CloseAppDomain((int) context); } else { if (object.ReferenceEquals(domain, s_ExcessAppDomain)) { try { AppDomain.Unload(domain); } catch (AppDomainUnloadedException) { } s_ExcessAppDomain = null; } } } catch (Exception exception) { if (NclUtilities.IsFatal(exception)) throw; } }
// // constructors // internal ServicePoint(Uri address, TimerThread.Queue defaultIdlingQueue, int defaultConnectionLimit, string lookupString, bool userChangedLimit, bool proxyServicePoint) { GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::.ctor(" + lookupString+")"); if (Logging.On) Logging.Enter(Logging.Web, this, "ServicePoint", address.DnsSafeHost + ":" + address.Port); m_ProxyServicePoint = proxyServicePoint; m_Address = address; m_ConnectionName = address.Scheme; m_Host = address.DnsSafeHost; m_Port = address.Port; m_IdlingQueue = defaultIdlingQueue; m_ConnectionLimit = defaultConnectionLimit; m_HostLoopbackGuess = TriState.Unspecified; m_LookupString = lookupString; m_UserChangedLimit = userChangedLimit; m_UseNagleAlgorithm = ServicePointManager.UseNagleAlgorithm; m_Expect100Continue = ServicePointManager.Expect100Continue; m_ConnectionGroupList = new Hashtable(10); m_ConnectionLeaseTimeout = System.Threading.Timeout.Infinite; m_ReceiveBufferSize = -1; m_UseTcpKeepAlive = ServicePointManager.s_UseTcpKeepAlive; m_TcpKeepAliveTime = ServicePointManager.s_TcpKeepAliveTime; m_TcpKeepAliveInterval = ServicePointManager.s_TcpKeepAliveInterval; // it would be safer to make sure the server is 1.1 // but assume it is at the beginning, and update it later m_Understands100Continue = true; m_HttpBehaviour = HttpBehaviour.Unknown; // upon creation, the service point should be idle, by default m_IdleSince = DateTime.Now; m_ExpiringTimer = m_IdlingQueue.CreateTimer(ServicePointManager.IdleServicePointTimeoutDelegate, this); m_IdleConnectionGroupTimeoutDelegate = new TimerThread.Callback(IdleConnectionGroupTimeoutCallback); }
/// <summary> /// <para>Because this is called from the timer thread, neither it nor any methods it calls can call user code.</para> /// </summary> private void TimerCallback(TimerThread.Timer timer, int timeNoticed, object context) { if (GlobalLog.IsEnabled) { GlobalLog.Print("FtpWebRequest#" + LoggingHash.HashString(this) + "::TimerCallback"); } FtpControlStream connection = _connection; if (connection != null) { if (GlobalLog.IsEnabled) { GlobalLog.Print("FtpWebRequest#" + LoggingHash.HashString(this) + "::TimerCallback aborting connection"); } connection.AbortConnect(); } }
private void IdleConnectionGroupTimeoutCallback(TimerThread.Timer timer, int timeNoticed, object context) { ConnectionGroup connectionGroup = (ConnectionGroup)context; if (Logging.On) Logging.PrintInfo(Logging.Web, this, SR.GetString(SR.net_log_closed_idle, "ConnectionGroup", connectionGroup.GetHashCode())); ReleaseConnectionGroup(connectionGroup.Name); }
private void TimerCallback(TimerThread.Timer timer, int timeNoticed, object context) { FtpControlStream connection = this.m_Connection; if (connection != null) { connection.AbortConnect(); } }
internal ServicePoint(string host, int port, TimerThread.Queue defaultIdlingQueue, int defaultConnectionLimit, string lookupString, bool userChangedLimit, bool proxyServicePoint) { GlobalLog.Print("ServicePoint#" + ValidationHelper.HashString(this) + "::.ctor(" + lookupString+")"); if (Logging.On) Logging.Enter(Logging.Web, this, "ServicePoint", host + ":" + port); m_ProxyServicePoint = proxyServicePoint; m_ConnectionName = "ByHost:"+host+":"+port.ToString(CultureInfo.InvariantCulture); m_IdlingQueue = defaultIdlingQueue; m_ConnectionLimit = defaultConnectionLimit; m_HostLoopbackGuess = TriState.Unspecified; m_LookupString = lookupString; m_UserChangedLimit = userChangedLimit; m_ConnectionGroupList = new Hashtable(10); m_ConnectionLeaseTimeout = System.Threading.Timeout.Infinite; m_ReceiveBufferSize = -1; m_Host = host; m_Port = port; m_HostMode = true; // upon creation, the service point should be idle, by default m_IdleSince = DateTime.Now; m_ExpiringTimer = m_IdlingQueue.CreateTimer(ServicePointManager.IdleServicePointTimeoutDelegate, this); m_IdleConnectionGroupTimeoutDelegate = new TimerThread.Callback(IdleConnectionGroupTimeoutCallback); }
/// <summary> /// <para>Because this is called from the timer thread, neither it nor any methods it calls can call user code.</para> /// </summary> private void TimerCallback(TimerThread.Timer timer, int timeNoticed, object context) { if (NetEventSource.IsEnabled) NetEventSource.Info(this); FtpControlStream connection = _connection; if (connection != null) { if (NetEventSource.IsEnabled) NetEventSource.Info(this, "aborting connection"); connection.AbortConnect(); } }
internal override TimerThread.Timer CreateTimer(TimerThread.Callback callback, object context) { return new TimerThread.InfiniteTimer(); }