diff --git a/OpenSim/Framework/Monitoring/Watchdog.cs b/OpenSim/Framework/Monitoring/Watchdog.cs index 9cc61ee62d..8a4894eb20 100644 --- a/OpenSim/Framework/Monitoring/Watchdog.cs +++ b/OpenSim/Framework/Monitoring/Watchdog.cs @@ -180,6 +180,30 @@ namespace OpenSim.Framework.Monitoring m_watchdogTimer.Elapsed += WatchdogTimerElapsed; } + public static void Stop() + { + if(m_threads == null) + return; + + lock(m_threads) + { + m_enabled = false; + if(m_watchdogTimer != null) + { + m_watchdogTimer.Dispose(); + m_watchdogTimer = null; + } + + foreach(ThreadWatchdogInfo twi in m_threads.Values) + { + Thread t = twi.Thread; + if(t.IsAlive) + t.Abort(); + } + m_threads.Clear(); + } + } + /// /// Add a thread to the watchdog tracker. /// diff --git a/OpenSim/Framework/Monitoring/WorkManager.cs b/OpenSim/Framework/Monitoring/WorkManager.cs index a3e03904eb..9d52f71f8d 100644 --- a/OpenSim/Framework/Monitoring/WorkManager.cs +++ b/OpenSim/Framework/Monitoring/WorkManager.cs @@ -85,6 +85,7 @@ namespace OpenSim.Framework.Monitoring public static void Stop() { JobEngine.Stop(); + Watchdog.Stop(); } /// diff --git a/OpenSim/Framework/Servers/BaseOpenSimServer.cs b/OpenSim/Framework/Servers/BaseOpenSimServer.cs index 2834d9437e..f832f81bc0 100644 --- a/OpenSim/Framework/Servers/BaseOpenSimServer.cs +++ b/OpenSim/Framework/Servers/BaseOpenSimServer.cs @@ -136,20 +136,21 @@ namespace OpenSim.Framework.Servers protected override void ShutdownSpecific() { - - + Watchdog.Enabled = false; base.ShutdownSpecific(); - + MainServer.Stop(); Thread.Sleep(5000); - + Util.StopThreadPool(); WorkManager.Stop(); + Thread.Sleep(1000); RemovePIDFile(); + m_log.Info("[SHUTDOWN]: Shutdown processing on main thread complete. Exiting..."); - if (!SuppressExit) + if (!SuppressExit) Environment.Exit(0); } diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs index 94a94904b8..ffc6ad3fee 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs @@ -91,7 +91,7 @@ namespace OpenSim.Framework.Servers.HttpServer PoolWorkerJob, string.Format("PollServiceWorkerThread {0}:{1}", i, m_server.Port), ThreadPriority.Normal, - false, + true, false, null, int.MaxValue); @@ -101,7 +101,7 @@ namespace OpenSim.Framework.Servers.HttpServer this.CheckRetries, string.Format("PollServiceWatcherThread:{0}", m_server.Port), ThreadPriority.Normal, - false, + true, true, null, 1000 * 60 * 10); diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index f6ded04cc1..5eedd2900b 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -2579,7 +2579,6 @@ namespace OpenSim.Framework } catch (ThreadAbortException e) { - m_log.Error(string.Format("Aborted threadfunc {0} ", threadFuncNum), e); } catch (Exception e) { @@ -2852,6 +2851,16 @@ namespace OpenSim.Framework return stpi; } + public static void StopThreadPool() + { + if (m_ThreadPool == null) + return; + SmartThreadPool pool = m_ThreadPool; + m_ThreadPool = null; + + try { pool.Shutdown(); } catch {} + } + #endregion FireAndForget Threading Pattern /// diff --git a/OpenSim/Region/Application/Application.cs b/OpenSim/Region/Application/Application.cs index 4bd2c28354..447afb4654 100644 --- a/OpenSim/Region/Application/Application.cs +++ b/OpenSim/Region/Application/Application.cs @@ -79,7 +79,7 @@ namespace OpenSim else { ServicePointManager.DefaultConnectionLimit = 12; - try { ServicePointManager.DnsRefreshTimeout = 120000; } // just is case crazy some mono decides to have it infinity + try { ServicePointManager.DnsRefreshTimeout = 120000; } // just is case some crazy mono decides to have it infinity catch { } } diff --git a/OpenSim/Region/Application/OpenSim.cs b/OpenSim/Region/Application/OpenSim.cs index 524f2be10b..5977f40bf0 100644 --- a/OpenSim/Region/Application/OpenSim.cs +++ b/OpenSim/Region/Application/OpenSim.cs @@ -143,7 +143,7 @@ namespace OpenSim //Mono.Unix.Native.Signum signal = signals [index].Signum; MainConsole.Instance.RunCommand("shutdown"); } - }); + }); #endif /// @@ -165,6 +165,7 @@ namespace OpenSim { new Mono.Unix.UnixSignal(Mono.Unix.Native.Signum.SIGTERM) }; + signal_thread.IsBackground = true; signal_thread.Start(); } catch (Exception e) @@ -485,6 +486,12 @@ namespace OpenSim RunCommandScript(m_shutdownCommandsFile); } + if (m_timedScript != "disabled") + { + m_scriptTimer.Dispose(); + m_timedScript = "disabled"; + } + base.ShutdownSpecific(); } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs index f733972d83..27db72cd7d 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs @@ -88,8 +88,8 @@ namespace OpenSim.Region.ClientStack.Linden private Dictionary m_capsDict = new Dictionary(); private static Thread[] m_workerThreads = null; private static int m_NumberScenes = 0; - private static OpenMetaverse.BlockingQueue m_queue = - new OpenMetaverse.BlockingQueue(); + private static OpenSim.Framework.BlockingQueue m_queue = + new OpenSim.Framework.BlockingQueue(); private Dictionary m_pollservices = new Dictionary(); @@ -170,7 +170,7 @@ namespace OpenSim.Region.ClientStack.Linden m_workerThreads[i] = WorkManager.StartThread(DoMeshRequests, String.Format("GetMeshWorker{0}", i), ThreadPriority.Normal, - false, + true, false, null, int.MaxValue); @@ -203,9 +203,12 @@ namespace OpenSim.Region.ClientStack.Linden { while(true) { - aPollRequest poolreq = m_queue.Dequeue(); + aPollRequest poolreq = m_queue.Dequeue(1000); + if(m_NumberScenes <= 0) + return; Watchdog.UpdateThread(); - poolreq.thepoll.Process(poolreq); + if(poolreq.reqID != UUID.Zero) + poolreq.thepoll.Process(poolreq); } } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs index c9f3b7eb11..d6b4873b76 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs @@ -77,8 +77,8 @@ namespace OpenSim.Region.ClientStack.Linden private Dictionary m_capsDict = new Dictionary(); private static Thread[] m_workerThreads = null; private static int m_NumberScenes = 0; - private static OpenMetaverse.BlockingQueue m_queue = - new OpenMetaverse.BlockingQueue(); + private static OpenSim.Framework.BlockingQueue m_queue = + new OpenSim.Framework.BlockingQueue(); private Dictionary m_pollservices = new Dictionary(); @@ -139,7 +139,7 @@ namespace OpenSim.Region.ClientStack.Linden m_workerThreads[i] = WorkManager.StartThread(DoTextureRequests, String.Format("GetTextureWorker{0}", i), ThreadPriority.Normal, - false, + true, false, null, int.MaxValue); @@ -274,7 +274,7 @@ namespace OpenSim.Region.ClientStack.Linden { if (responses.Count > 0) { - if (m_queue.Count >= 4) + if (m_queue.Count() >= 4) { // Never allow more than 4 fetches to wait reqinfo.send503 = true; @@ -445,9 +445,12 @@ namespace OpenSim.Region.ClientStack.Linden { while (true) { - aPollRequest poolreq = m_queue.Dequeue(); + aPollRequest poolreq = m_queue.Dequeue(2000); + if(m_NumberScenes <= 0) + return; Watchdog.UpdateThread(); - poolreq.thepoll.Process(poolreq); + if(poolreq.reqID != UUID.Zero) + poolreq.thepoll.Process(poolreq); } } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index 1ea0454d7f..422c3540c6 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs @@ -206,7 +206,7 @@ namespace OpenSim.Region.ClientStack.Linden m_workerThreads[i] = WorkManager.StartThread(DoInventoryRequests, String.Format("InventoryWorkerThread{0}", i), ThreadPriority.Normal, - false, + true, true, null, int.MaxValue); diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 4b846f50d9..ca2060439a 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -527,15 +527,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { string homeURI = Scene.GetAgentHomeURI(sp.ControllingClient.AgentId); - string message; - finalDestination = GetFinalDestination(reg, sp.ControllingClient.AgentId, homeURI, out message); + string reason = String.Empty; + finalDestination = GetFinalDestination(reg, sp.ControllingClient.AgentId, homeURI, out reason); if (finalDestination == null) { m_log.WarnFormat( "{0} Final destination is having problems. Unable to teleport {1} {2}: {3}", - LogHeader, sp.Name, sp.UUID, message); + LogHeader, sp.Name, sp.UUID, reason); - sp.ControllingClient.SendTeleportFailed(message); + sp.ControllingClient.SendTeleportFailed(reason); return; } @@ -548,17 +548,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } - // Validate assorted conditions - string reason = string.Empty; if (!ValidateGenericConditions(sp, reg, finalDestination, teleportFlags, out reason)) { sp.ControllingClient.SendTeleportFailed(reason); return; } - if (message != null) - sp.ControllingClient.SendAgentAlertMessage(message, true); - // // This is it // @@ -735,8 +730,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer IPEndPoint endPoint = finalDestination.ExternalEndPoint; if (endPoint == null || endPoint.Address == null) { - sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); - + sp.ControllingClient.SendTeleportFailed("Could not resolve destination Address"); return; } @@ -784,22 +778,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // At least on LL 3.3.4, this is not strictly necessary - a teleport will succeed without sending this to // the viewer. However, it might mean that the viewer does not see the black teleport screen (untested). sp.ControllingClient.SendTeleportStart(teleportFlags); - - // the avatar.Close below will clear the child region list. We need this below for (possibly) - // closing the child agents, so save it here (we need a copy as it is Clear()-ed). - //List childRegions = avatar.KnownRegionHandles; - // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport - // failure at this point (unlike a border crossing failure). So perhaps this can never fail - // once we reach here... - //avatar.Scene.RemoveCapsHandler(avatar.UUID); - + AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); agentCircuit.startpos = position; agentCircuit.child = true; -// agentCircuit.Appearance = sp.Appearance; -// agentCircuit.Appearance = new AvatarAppearance(sp.Appearance, true, false); agentCircuit.Appearance = new AvatarAppearance(); agentCircuit.Appearance.AvatarHeight = sp.Appearance.AvatarHeight; @@ -1673,6 +1657,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return agent; } + IPEndPoint endpoint = neighbourRegion.ExternalEndPoint; + if(endpoint == null) + { + m_log.DebugFormat("{0}: CrossAgentToNewRegionAsync: failed to resolve neighbour address {0} ",neighbourRegion.ExternalHostName); + return agent; + } + m_entityTransferStateMachine.SetInTransit(agent.UUID); agent.RemoveFromPhysicalScene(); @@ -1683,7 +1674,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return agent; } - CrossAgentToNewRegionPost(agent, pos, neighbourRegion, isFlying, ctx); + CrossAgentToNewRegionPost(agent, pos, neighbourRegion, endpoint, isFlying, ctx); } catch (Exception e) { @@ -1727,6 +1718,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer agent.AddNeighbourRegion(neighbourRegion, agentCircuit.CapsPath); IPEndPoint endPoint = neighbourRegion.ExternalEndPoint; + if(endPoint == null) + { + m_log.DebugFormat("CrossAgentCreateFarChild failed to resolve neighbour address {0}", neighbourRegion.ExternalHostName); + return false; + } if (Scene.SimulationService.CreateAgent(source, neighbourRegion, agentCircuit, (int)TeleportFlags.Default, ctx, out reason)) { string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); @@ -1821,7 +1817,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } public void CrossAgentToNewRegionPost(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, - bool isFlying, EntityTransferContext ctx) + IPEndPoint endpoint, bool isFlying, EntityTransferContext ctx) { string agentcaps; @@ -1848,15 +1844,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { m_eqModule.CrossRegion( neighbourRegion.RegionHandle, pos, vel2 /* agent.Velocity */, - neighbourRegion.ExternalEndPoint, - capsPath, agent.UUID, agent.ControllingClient.SessionId, + endpoint, capsPath, agent.UUID, agent.ControllingClient.SessionId, neighbourRegion.RegionSizeX, neighbourRegion.RegionSizeY); } else { m_log.ErrorFormat("{0} Using old CrossRegion packet. Varregion will not work!!", LogHeader); - agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint, - capsPath); + agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos, agent.Velocity, + endpoint,capsPath); } // SUCCESS! @@ -1953,7 +1948,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer seeds.Add(regionhandler, agent.CapsPath); - // agent.ChildrenCapSeeds = new Dictionary(seeds); agent.ChildrenCapSeeds = null; diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs index eb6455a6fb..1688aa63ea 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs @@ -188,9 +188,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api cmdHandlerThreadCycleSleepms = 100; } +/* ~AsyncCommandManager() { // Shut down thread + try { lock (staticLock) @@ -213,7 +215,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { } } - +*/ /// /// Main loop for the manager thread /// @@ -229,6 +231,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api Watchdog.UpdateThread(); } + catch ( System.Threading.ThreadAbortException) { } catch (Exception e) { m_log.Error("[ASYNC COMMAND MANAGER]: Exception in command handler pass: ", e); diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs index 2e3903393e..c1abba2818 100755 --- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs +++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs @@ -1079,6 +1079,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine "[XEngine]: Started {0} scripts in {1}", scriptsStarted, m_Scene.Name); } } + catch (System.Threading.ThreadAbortException) { } catch (Exception e) { m_log.Error( diff --git a/OpenSim/Server/Base/ServicesServerBase.cs b/OpenSim/Server/Base/ServicesServerBase.cs index 4951776cf9..176e876af3 100644 --- a/OpenSim/Server/Base/ServicesServerBase.cs +++ b/OpenSim/Server/Base/ServicesServerBase.cs @@ -211,6 +211,7 @@ namespace OpenSim.Server.Base { new Mono.Unix.UnixSignal(Mono.Unix.Native.Signum.SIGTERM) }; + ignal_thread.IsBackground = true; signal_thread.Start(); } catch (Exception e) @@ -249,6 +250,9 @@ namespace OpenSim.Server.Base } } + MemoryWatchdog.Enabled = false; + Watchdog.Enabled = false; + WorkManager.Stop(); RemovePIDFile(); return 0; diff --git a/OpenSim/Server/ServerMain.cs b/OpenSim/Server/ServerMain.cs index a331b39690..5c99ab7b8b 100644 --- a/OpenSim/Server/ServerMain.cs +++ b/OpenSim/Server/ServerMain.cs @@ -33,6 +33,7 @@ using System.Net; using System.Net.Security; using System.Security.Cryptography.X509Certificates; using System.Collections.Generic; +using OpenSim.Framework; using OpenSim.Framework.Servers; using OpenSim.Framework.Servers.HttpServer; using OpenSim.Server.Base; @@ -188,6 +189,11 @@ namespace OpenSim.Server int res = m_Server.Run(); + if(m_Server != null) + m_Server.Shutdown(); + + Util.StopThreadPool(); + Environment.Exit(res); return 0; diff --git a/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs b/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs index 810da2f7cc..2deb2d1100 100644 --- a/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs +++ b/OpenSim/Services/Connectors/Asset/AssetServicesConnector.cs @@ -135,8 +135,7 @@ namespace OpenSim.Services.Connectors for (int i = 0 ; i < 2 ; i++) { - m_fetchThreads[i] = new Thread(AssetRequestProcessor); - m_fetchThreads[i].Start(); + Util.FireAndForget(delegate { AssetRequestProcessor();}); } } @@ -349,8 +348,8 @@ namespace OpenSim.Services.Connectors public string id; } - private OpenMetaverse.BlockingQueue m_requestQueue = - new OpenMetaverse.BlockingQueue(); + private OpenSim.Framework.BlockingQueue m_requestQueue = + new OpenSim.Framework.BlockingQueue(); private void AssetRequestProcessor() { @@ -358,8 +357,9 @@ namespace OpenSim.Services.Connectors while (true) { - r = m_requestQueue.Dequeue(); - + r = m_requestQueue.Dequeue(2000); + if(r== null) + continue; string uri = r.uri; string id = r.id; diff --git a/OpenSim/Services/Interfaces/IGridService.cs b/OpenSim/Services/Interfaces/IGridService.cs index 66e58702fb..8068ff5cc4 100644 --- a/OpenSim/Services/Interfaces/IGridService.cs +++ b/OpenSim/Services/Interfaces/IGridService.cs @@ -271,31 +271,6 @@ namespace OpenSim.Services.Interfaces m_serverURI = string.Empty; } - /* - public GridRegion(int regionLocX, int regionLocY, IPEndPoint internalEndPoint, string externalUri) - { - m_regionLocX = regionLocX; - m_regionLocY = regionLocY; - RegionSizeX = (int)Constants.RegionSize; - RegionSizeY = (int)Constants.RegionSize; - - m_internalEndPoint = internalEndPoint; - m_externalHostName = externalUri; - } - - public GridRegion(int regionLocX, int regionLocY, string externalUri, uint port) - { - m_regionLocX = regionLocX; - m_regionLocY = regionLocY; - RegionSizeX = (int)Constants.RegionSize; - RegionSizeY = (int)Constants.RegionSize; - - m_externalHostName = externalUri; - - m_internalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), (int)port); - } - */ - public GridRegion(uint xcell, uint ycell) { m_regionLocX = (int)Util.RegionToWorldLoc(xcell); @@ -489,14 +464,16 @@ namespace OpenSim.Services.Interfaces { get { - // Old one defaults to IPv6 - //return new IPEndPoint(Dns.GetHostAddresses(m_externalHostName)[0], m_internalEndPoint.Port); - IPAddress ia = null; // If it is already an IP, don't resolve it - just return directly + // we should not need this if (IPAddress.TryParse(m_externalHostName, out ia)) + { + if (ia.Equals(IPAddress.Any) || ia.Equals(IPAddress.IPv6Any)) + return null; return new IPEndPoint(ia, m_internalEndPoint.Port); - + } + // Reset for next check ia = null; try @@ -513,7 +490,7 @@ namespace OpenSim.Services.Interfaces } } } - catch (SocketException e) + catch // (SocketException e) { /*throw new Exception( "Unable to resolve local hostname " + m_externalHostName + " innerException of type '" + @@ -524,6 +501,9 @@ namespace OpenSim.Services.Interfaces return null; } + if(ia == null) + return null; + return new IPEndPoint(ia, m_internalEndPoint.Port); } } diff --git a/bin/lib32/libode.dylib b/bin/lib32/libode.dylib old mode 100644 new mode 100755 index ce0d5d0be6..fa3c070b71 Binary files a/bin/lib32/libode.dylib and b/bin/lib32/libode.dylib differ diff --git a/bin/lib32/libode.so b/bin/lib32/libode.so index 3e08c42d89..47991aeefb 100755 Binary files a/bin/lib32/libode.so and b/bin/lib32/libode.so differ diff --git a/bin/lib64/libode-x86_64.so b/bin/lib64/libode-x86_64.so index 2f616dde65..17502c5a50 100755 Binary files a/bin/lib64/libode-x86_64.so and b/bin/lib64/libode-x86_64.so differ diff --git a/bin/lib64/libode.dylib b/bin/lib64/libode.dylib old mode 100644 new mode 100755 index ce0d5d0be6..fa3c070b71 Binary files a/bin/lib64/libode.dylib and b/bin/lib64/libode.dylib differ