private void SlowTimerCallback(object state) { try { int start = m_timerTickStart; GameTimer timer = m_currentTimer; if (timer == null) { return; } StringBuilder str = new StringBuilder("=== Timer already took ", 1024); str.Append(GetTickCount() - start).Append("ms\n"); str.Append(timer.ToString()); str.Append("\n\n"); str.Append("Timer thread:\n"); str.Append(Util.FormatStackTrace(Util.GetThreadStack(m_timeThread))); string packetStacks = PacketHandler.PacketProcessor.GetConnectionThreadpoolStacks(); if (packetStacks.Length > 0) { str.Append("\n\nPackethandler threads:\n"); str.Append(packetStacks); } str.Append("\n\nNPC update thread:\n"); str.Append(Util.FormatStackTrace(WorldMgr.GetNpcUpdateStacktrace())); str.Append("\n\nRelocation thread:\n"); str.Append(Util.FormatStackTrace(WorldMgr.GetRelocateRegionsStacktrace())); str.Append("\n\n"); lock (m_delayLog) { m_delayLog.Write(str.ToString()); m_delayLog.Flush(); } } catch (Exception e) { if (log.IsWarnEnabled) { log.Warn("collecting/writing timer delays", e); } } }
/// <summary> /// Stops the time manager if not stopped already /// </summary> /// <returns>success</returns> public bool Stop() { if (m_timeThread == null) { return(false); } lock (m_lockObject) { m_running = false; if (!m_timeThread.Join(10000)) { try { if (log.IsErrorEnabled) { ThreadState state = m_timeThread.ThreadState; StackTrace trace = Util.GetThreadStack(m_timeThread); log.ErrorFormat("failed to stop the time thread \"{0}\" in 10 seconds (thread state={1}); thread stacktrace:\n", m_name, state); log.ErrorFormat(Util.FormatStackTrace(trace)); log.ErrorFormat("aborting the thread.\n"); } } finally { m_timeThread.Abort(); try { while (!m_timeThread.Join(2000)) { log.ErrorFormat("Timer Thread ({0}) can't stop after abort... maybe remaining threads going... trying again !"); try { m_timeThread.Abort(); } catch { } } } catch { } } } m_timeThread = null; Array.Clear(m_buckets, 0, m_buckets.Length); Array.Clear(m_cachedBucket, 0, m_cachedBucket.Length); #if MonitorCallbacks try { m_delayLog.Flush(); m_delayLog.Close(); } catch (Exception e) { log.Error("Closing delays log while stop() " + m_name, e); } #endif return(true); } }