/// <summary> /// Wait out termination of a thread pool or fail doing so /// </summary> public void JoinPool(ThreadPoolExecutor exec) { try { exec.Shutdown(); Assert.IsTrue(exec.AwaitTermination(TimeSpan.FromSeconds(20))); } catch (Exception) { Assert.Fail("Unexpected exception"); } }
public void TestAwaitTermination() { ThreadPoolExecutor executor = new ThreadPoolExecutor(); Assert.IsNotNull(executor); Assert.IsFalse(executor.IsShutdown); Assert.IsFalse(executor.IsTerminated); executor.QueueUserWorkItem(TaskThatSleeps); executor.Shutdown(); Assert.IsFalse(executor.IsTerminated, "Terminated before await."); Assert.IsFalse(executor.AwaitTermination(TimeSpan.FromMilliseconds(500)), "Should be terminated yet."); Assert.IsFalse(executor.IsTerminated, "Terminated after await."); JoinPool(executor); Assert.IsTrue(executor.IsTerminated); }
/// <summary>Wait for the termination of the thread pools.</summary> /// <param name="milliseconds">The number of milliseconds to wait</param> /// <returns>true if all thread pools are terminated without time limit</returns> /// <exception cref="System.Exception"></exception> public virtual bool AwaitTermination(long milliseconds) { lock (this) { long end = Time.Now() + milliseconds; foreach (KeyValuePair <string, ThreadPoolExecutor> e in executors) { ThreadPoolExecutor executor = e.Value; if (!executor.AwaitTermination(Math.Max(end - Time.Now(), 0), TimeUnit.Milliseconds )) { Log.Warn("AsyncDiskService awaitTermination timeout."); return(false); } } Log.Info("All AsyncDiskService threads are terminated."); return(true); } }
public void Stop() { // Changing the isStarted flag will signal the thread that it needs to shut down. if (started.CompareAndSet(true, false)) { DoStopAgent(); if (worker != null) { // wait for the worker to stop. if (!worker.Join(WORKER_KILL_TIME_SECONDS)) { Tracer.Info("!! Timeout waiting for discovery agent localThread to stop"); worker.Abort(); } worker = null; Tracer.Debug("Multicast discovery agent worker thread stopped"); } executor.Shutdown(); if (!executor.AwaitTermination(TimeSpan.FromMinutes(1))) { Tracer.DebugFormat("Failed to properly shutdown agent executor {0}", this); } } }
public void Close() { if (!this.closed.Value && !transportFailed.Value) { this.Stop(); } lock (connectedLock) { if (this.closed.Value) { return; } try { Tracer.InfoFormat("Connection[{0}]: Closing Connection Now.", this.ClientId); this.closing.Value = true; Scheduler scheduler = this.scheduler; if (scheduler != null) { try { scheduler.Stop(); } catch (Exception e) { throw NMSExceptionSupport.Create(e); } } lock (sessions.SyncRoot) { foreach (Session session in sessions) { session.Shutdown(); } } sessions.Clear(); // Connected is true only when we've successfully sent our CONNECT // to the broker, so if we haven't announced ourselves there's no need to // inform the broker of a remove, and if the transport is failed, why bother. if (connected.Value && !transportFailed.Value) { DISCONNECT disconnect = new DISCONNECT(); transport.Oneway(disconnect); } executor.Shutdown(); if (!executor.AwaitTermination(TimeSpan.FromMinutes(1))) { Tracer.DebugFormat("Connection[{0}]: Failed to properly shutdown its executor", this.ClientId); } Tracer.DebugFormat("Connection[{0}]: Disposing of the Transport.", this.ClientId); transport.Stop(); transport.Dispose(); } catch (Exception ex) { Tracer.ErrorFormat("Connection[{0}]: Error during connection close: {1}", ClientId, ex); } finally { if (executor != null) { executor.Shutdown(); } this.transport = null; this.closed.Value = true; this.connected.Value = false; this.closing.Value = false; } } }