From 2f394b7e7ebf991c7a70f93bf251d26d8043aaa2 Mon Sep 17 00:00:00 2001
From: John Hurliman
Date: Thu, 22 Oct 2009 01:30:12 -0700
Subject: * Allow SmartThreadPool to be initialized without setting max stack
size (like the original implementation) * Only initialize Util's
SmartThreadPool if it is actually being used * No longer initializing Util's
SmartThreadPool with a custom max stack size. From MSDN: "Avoid using this
constructor overload. The default stack size used by the Thread(ThreadStart)
constructor overload is the recommended stack size for threads."
---
OpenSim/Framework/Util.cs | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
(limited to 'OpenSim/Framework')
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index d09bd6d..167e34d 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -69,8 +69,6 @@ namespace OpenSim.Framework
///
public class Util
{
- private static SmartThreadPool m_ThreadPool = null;
-
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static uint nextXferID = 5000;
@@ -79,6 +77,9 @@ namespace OpenSim.Framework
private static string regexInvalidFileChars = "[" + new String(Path.GetInvalidFileNameChars()) + "]";
private static string regexInvalidPathChars = "[" + new String(Path.GetInvalidPathChars()) + "]";
private static object XferLock = new object();
+ /// Thread pool used for Util.FireAndForget if
+ /// FireAndForgetMethod.SmartThreadPool is used
+ private static SmartThreadPool m_ThreadPool;
// Unix-epoch starts at January 1st 1970, 00:00:00 UTC. And all our times in the server are (or at least should be) in UTC.
private static readonly DateTime unixEpoch =
@@ -1319,8 +1320,11 @@ namespace OpenSim.Framework
FireAndForget(callback, null);
}
- public static void SetMaxThreads(int maxThreads)
+ public static void InitThreadPool(int maxThreads)
{
+ if (maxThreads < 2)
+ throw new ArgumentOutOfRangeException("maxThreads", "maxThreads must be greater than 2");
+
if (m_ThreadPool != null)
return;
@@ -1328,9 +1332,7 @@ namespace OpenSim.Framework
startInfo.IdleTimeout = 2000; // 2 seconds
startInfo.MaxWorkerThreads = maxThreads;
startInfo.MinWorkerThreads = 2;
- startInfo.StackSize = 524288;
startInfo.ThreadPriority = ThreadPriority.Normal;
-
startInfo.StartSuspended = false;
m_ThreadPool = new SmartThreadPool(startInfo);
--
cgit v1.1
From d756fa01aea63e9b50be00a6f1f229ff7afef779 Mon Sep 17 00:00:00 2001
From: Jeff Ames
Date: Thu, 22 Oct 2009 18:57:14 +0900
Subject: Add copyright header. Formatting cleanup.
---
OpenSim/Framework/MinHeap.cs | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
mode change 100755 => 100644 OpenSim/Framework/MinHeap.cs
(limited to 'OpenSim/Framework')
diff --git a/OpenSim/Framework/MinHeap.cs b/OpenSim/Framework/MinHeap.cs
old mode 100755
new mode 100644
index ad39bbc..33d0364
--- a/OpenSim/Framework/MinHeap.cs
+++ b/OpenSim/Framework/MinHeap.cs
@@ -1,3 +1,30 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSimulator Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
using System;
using System.Threading;
using System.Collections;
--
cgit v1.1
From 6ca4b0f36622833688136e9ace7d5545063293ba Mon Sep 17 00:00:00 2001
From: John Hurliman
Date: Thu, 22 Oct 2009 10:37:11 -0700
Subject: * Added a check if Util.m_ThreadPool is null before trying to use it,
and if so initialize it to sane defaults * Simplified the InitThreadPool()
function
---
OpenSim/Framework/Util.cs | 20 +++++++-------------
1 file changed, 7 insertions(+), 13 deletions(-)
(limited to 'OpenSim/Framework')
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index 167e34d..a18a827 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -1324,18 +1324,10 @@ namespace OpenSim.Framework
{
if (maxThreads < 2)
throw new ArgumentOutOfRangeException("maxThreads", "maxThreads must be greater than 2");
-
if (m_ThreadPool != null)
- return;
-
- STPStartInfo startInfo = new STPStartInfo();
- startInfo.IdleTimeout = 2000; // 2 seconds
- startInfo.MaxWorkerThreads = maxThreads;
- startInfo.MinWorkerThreads = 2;
- startInfo.ThreadPriority = ThreadPriority.Normal;
- startInfo.StartSuspended = false;
+ throw new InvalidOperationException("SmartThreadPool is already initialized");
- m_ThreadPool = new SmartThreadPool(startInfo);
+ m_ThreadPool = new SmartThreadPool(2000, maxThreads, 2);
}
public static void FireAndForget(System.Threading.WaitCallback callback, object obj)
@@ -1343,20 +1335,22 @@ namespace OpenSim.Framework
switch (FireAndForgetMethod)
{
case FireAndForgetMethod.UnsafeQueueUserWorkItem:
- System.Threading.ThreadPool.UnsafeQueueUserWorkItem(callback, obj);
+ ThreadPool.UnsafeQueueUserWorkItem(callback, obj);
break;
case FireAndForgetMethod.QueueUserWorkItem:
- System.Threading.ThreadPool.QueueUserWorkItem(callback, obj);
+ ThreadPool.QueueUserWorkItem(callback, obj);
break;
case FireAndForgetMethod.BeginInvoke:
FireAndForgetWrapper wrapper = Singleton.GetInstance();
wrapper.FireAndForget(callback, obj);
break;
case FireAndForgetMethod.SmartThreadPool:
+ if (m_ThreadPool != null)
+ m_ThreadPool = new SmartThreadPool(2000, 15, 2);
m_ThreadPool.QueueWorkItem(delegate(object o) { callback(o); return null; }, obj);
break;
case FireAndForgetMethod.Thread:
- System.Threading.Thread thread = new System.Threading.Thread(delegate(object o) { callback(o); });
+ Thread thread = new Thread(delegate(object o) { callback(o); });
thread.Start(obj);
break;
default:
--
cgit v1.1
From 36b0e5e1d3112212ef988a8b2e7c10284c7e9276 Mon Sep 17 00:00:00 2001
From: John Hurliman
Date: Thu, 22 Oct 2009 11:07:23 -0700
Subject: Terrible typo in the previous commit!
---
OpenSim/Framework/Util.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'OpenSim/Framework')
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index a18a827..b96367a 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -1345,7 +1345,7 @@ namespace OpenSim.Framework
wrapper.FireAndForget(callback, obj);
break;
case FireAndForgetMethod.SmartThreadPool:
- if (m_ThreadPool != null)
+ if (m_ThreadPool == null)
m_ThreadPool = new SmartThreadPool(2000, 15, 2);
m_ThreadPool.QueueWorkItem(delegate(object o) { callback(o); return null; }, obj);
break;
--
cgit v1.1
From b2ed348aa2746fbf034b713d006e40366c479d5a Mon Sep 17 00:00:00 2001
From: John Hurliman
Date: Thu, 22 Oct 2009 12:33:23 -0700
Subject: Implemented a Watchdog class. Do not manually create Thread objects
anymore, use Watchdog.StartThread(). While your thread is running call
Watchdog.UpdateThread(). When it is shutting down call
Watchdog.RemoveThread(). Most of the threads in OpenSim have been updated
---
.../Framework/Servers/HttpServer/BaseHttpServer.cs | 8 -
.../HttpServer/PollServiceRequestManager.cs | 6 +-
OpenSim/Framework/Watchdog.cs | 183 +++++++++++++++++++++
3 files changed, 185 insertions(+), 12 deletions(-)
create mode 100644 OpenSim/Framework/Watchdog.cs
(limited to 'OpenSim/Framework')
diff --git a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
index 85d7be2..bec5ed3 100644
--- a/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
+++ b/OpenSim/Framework/Servers/HttpServer/BaseHttpServer.cs
@@ -1559,15 +1559,7 @@ namespace OpenSim.Framework.Servers.HttpServer
public void Start()
{
m_log.Info("[HTTPD]: Starting up HTTP Server");
-
- //m_workerThread = new Thread(new ThreadStart(StartHTTP));
- //m_workerThread.Name = "HttpThread";
- //m_workerThread.IsBackground = true;
- //m_workerThread.Start();
- //ThreadTracker.Add(m_workerThread);
StartHTTP();
-
-
}
private void StartHTTP()
diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
index 1c54581..e7a64f7 100644
--- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
+++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs
@@ -50,9 +50,7 @@ namespace OpenSim.Framework.Servers.HttpServer
m_WorkerThreadCount = pWorkerThreadCount;
m_workerThreads = new Thread[m_WorkerThreadCount];
m_PollServiceWorkerThreads = new PollServiceWorkerThread[m_WorkerThreadCount];
- m_watcherThread = new Thread(ThreadStart);
-
//startup worker threads
for (uint i=0;i
+ /// Manages launching threads and keeping watch over them for timeouts
+ ///
+ public static class Watchdog
+ {
+ /// Timer interval in milliseconds for the watchdog timer
+ const double WATCHDOG_INTERVAL_MS = 2500.0d;
+ /// Maximum timeout in milliseconds before a thread is considered dead
+ const int WATCHDOG_TIMEOUT_MS = 5000;
+
+ [System.Diagnostics.DebuggerDisplay("{Thread.Name}")]
+ private class ThreadWatchdogInfo
+ {
+ public Thread Thread;
+ public int LastTick;
+
+ public ThreadWatchdogInfo(Thread thread)
+ {
+ Thread = thread;
+ LastTick = Environment.TickCount & Int32.MaxValue;
+ }
+ }
+
+ ///
+ /// This event is called whenever a tracked thread is stopped or
+ /// has not called UpdateThread() in time
+ ///
+ /// The thread that has been identified as dead
+ /// The last time this thread called UpdateThread()
+ public delegate void WatchdogTimeout(Thread thread, int lastTick);
+
+ /// This event is called whenever a tracked thread is
+ /// stopped or has not called UpdateThread() in time
+ public static event WatchdogTimeout OnWatchdogTimeout;
+
+ private static Dictionary m_threads;
+ private static System.Timers.Timer m_watchdogTimer;
+
+ static Watchdog()
+ {
+ m_threads = new Dictionary();
+ m_watchdogTimer = new System.Timers.Timer(WATCHDOG_INTERVAL_MS);
+ m_watchdogTimer.AutoReset = false;
+ m_watchdogTimer.Elapsed += WatchdogTimerElapsed;
+ m_watchdogTimer.Start();
+ }
+
+ ///
+ /// Start a new thread that is tracked by the watchdog timer
+ ///
+ /// The method that will be executed in a new thread
+ /// A name to give to the new thread
+ /// Priority to run the thread at
+ /// True to run this thread as a background
+ /// thread, otherwise false
+ /// The newly created Thread object
+ public static Thread StartThread(ThreadStart start, string name, ThreadPriority priority, bool isBackground)
+ {
+ Thread thread = new Thread(start);
+ thread.Name = name;
+ thread.Priority = priority;
+ thread.IsBackground = isBackground;
+ thread.Start();
+
+ lock (m_threads)
+ m_threads.Add(thread.ManagedThreadId, new ThreadWatchdogInfo(thread));
+
+ return thread;
+ }
+
+ ///
+ /// Marks the current thread as alive
+ ///
+ public static void UpdateThread()
+ {
+ UpdateThread(Thread.CurrentThread.ManagedThreadId);
+ }
+
+ ///
+ /// Marks a thread as alive
+ ///
+ /// The ManagedThreadId of the thread to mark as
+ /// alive
+ public static void UpdateThread(int threadID)
+ {
+ ThreadWatchdogInfo threadInfo;
+
+ lock (m_threads)
+ {
+ if (m_threads.TryGetValue(threadID, out threadInfo))
+ {
+ threadInfo.LastTick = Environment.TickCount & Int32.MaxValue;
+ }
+ }
+ }
+
+ ///
+ /// Stops watchdog tracking on the current thread
+ ///
+ /// True if the thread was removed from the list of tracked
+ /// threads, otherwise false
+ public static bool RemoveThread()
+ {
+ return RemoveThread(Thread.CurrentThread.ManagedThreadId);
+ }
+
+ ///
+ /// Stops watchdog tracking on a thread
+ ///
+ /// The ManagedThreadId of the thread to stop
+ /// tracking
+ /// True if the thread was removed from the list of tracked
+ /// threads, otherwise false
+ public static bool RemoveThread(int threadID)
+ {
+ lock (m_threads)
+ return m_threads.Remove(threadID);
+ }
+
+ private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
+ {
+ WatchdogTimeout callback = OnWatchdogTimeout;
+
+ if (callback != null)
+ {
+ ThreadWatchdogInfo timedOut = null;
+
+ lock (m_threads)
+ {
+ int now = Environment.TickCount;
+
+ foreach (ThreadWatchdogInfo threadInfo in m_threads.Values)
+ {
+ if (threadInfo.Thread.ThreadState == ThreadState.Stopped || now - threadInfo.LastTick >= WATCHDOG_TIMEOUT_MS)
+ {
+ timedOut = threadInfo;
+ m_threads.Remove(threadInfo.Thread.ManagedThreadId);
+ break;
+ }
+ }
+ }
+
+ if (timedOut != null)
+ callback(timedOut.Thread, timedOut.LastTick);
+ }
+
+ m_watchdogTimer.Start();
+ }
+ }
+}
--
cgit v1.1
From a41cd1d0695c01e4096fa0b7696b415a4c7455fc Mon Sep 17 00:00:00 2001
From: John Hurliman
Date: Fri, 23 Oct 2009 13:14:29 -0700
Subject: * Unregister Mono.Addins event handlers in PluginLoader.Dispose() and
always handle PluginLoader with the using pattern. This freed up 121,634,796
bytes on my system * Avoid allocating an Action object every
round of the OutgoingPacketHandler * Removed unnecessary semi-colon endings
from OpenSim.ini.example [InterestManagement] section
---
OpenSim/Framework/PluginLoader.cs | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
(limited to 'OpenSim/Framework')
diff --git a/OpenSim/Framework/PluginLoader.cs b/OpenSim/Framework/PluginLoader.cs
index 5d38f5f..819cb7b 100644
--- a/OpenSim/Framework/PluginLoader.cs
+++ b/OpenSim/Framework/PluginLoader.cs
@@ -194,10 +194,15 @@ namespace OpenSim.Framework
}
}
+ ///
+ /// Unregisters Mono.Addins event handlers, allowing temporary Mono.Addins
+ /// data to be garbage collected. Since the plugins created by this loader
+ /// are meant to outlive the loader itself, they must be disposed separately
+ ///
public void Dispose()
{
- foreach (T plugin in Plugins)
- plugin.Dispose();
+ AddinManager.AddinLoadError -= on_addinloaderror_;
+ AddinManager.AddinLoaded -= on_addinloaded_;
}
private void initialise_plugin_dir_(string dir)
--
cgit v1.1
From 52a4534f7fe9e7b044a54f5a794391b54a1edb94 Mon Sep 17 00:00:00 2001
From: John Hurliman
Date: Fri, 23 Oct 2009 13:45:18 -0700
Subject: * Change the way Util.FireAndForget() calls SmartThreadPool to avoid
using a delegate (which STP appears to hold on to). This removes the slow
leak I was seeing when using async_call_method=SmartThreadPool and stabilizes
allocated memory for an idle OpenSim instance
---
OpenSim/Framework/Util.cs | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
(limited to 'OpenSim/Framework')
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs
index b96367a..10f38ab 100644
--- a/OpenSim/Framework/Util.cs
+++ b/OpenSim/Framework/Util.cs
@@ -1347,7 +1347,7 @@ namespace OpenSim.Framework
case FireAndForgetMethod.SmartThreadPool:
if (m_ThreadPool == null)
m_ThreadPool = new SmartThreadPool(2000, 15, 2);
- m_ThreadPool.QueueWorkItem(delegate(object o) { callback(o); return null; }, obj);
+ m_ThreadPool.QueueWorkItem(SmartThreadPoolCallback, new object[] { callback, obj });
break;
case FireAndForgetMethod.Thread:
Thread thread = new Thread(delegate(object o) { callback(o); });
@@ -1358,6 +1358,16 @@ namespace OpenSim.Framework
}
}
+ private static object SmartThreadPoolCallback(object o)
+ {
+ object[] array = (object[])o;
+ WaitCallback callback = (WaitCallback)array[0];
+ object obj = array[1];
+
+ callback(obj);
+ return null;
+ }
+
#endregion FireAndForget Threading Pattern
}
}
--
cgit v1.1
From 730930955a7edc0bfa69ff1cac93acd024cf8d24 Mon Sep 17 00:00:00 2001
From: John Hurliman
Date: Sun, 25 Oct 2009 00:40:21 -0700
Subject: Changing Scene.ForEachClient to use the synchronous for loop instead
of Parallel. This is quite possibly the source of some deadlocking, and at
the very least the synchronous version gives better stack traces * Lock the
LLUDPClient RTO math * Add a helper function for backing off the RTO, and
follow the optional advice in RFC 2988 to clear existing SRTT and RTTVAR
values during a backoff
* Removing the unused PrimitiveBaseShape.SculptImage parameter * Improved performance of SceneObjectPart instantiation * ZeroMesher now drops SculptData bytes like Meshmerizer, to allow the texture data to be GCed * Improved typecasting speed in MySQLLegacyRegionData.BuildShape()
* Improved the instantiation of PrimitiveBaseShape
---
OpenSim/Framework/PrimitiveBaseShape.cs | 66 +++++++++++++--------------------
1 file changed, 25 insertions(+), 41 deletions(-)
(limited to 'OpenSim/Framework')
diff --git a/OpenSim/Framework/PrimitiveBaseShape.cs b/OpenSim/Framework/PrimitiveBaseShape.cs
index b646f92..5e4d175 100644
--- a/OpenSim/Framework/PrimitiveBaseShape.cs
+++ b/OpenSim/Framework/PrimitiveBaseShape.cs
@@ -76,7 +76,7 @@ namespace OpenSim.Framework
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
- private static readonly Primitive.TextureEntry m_defaultTexture;
+ private static readonly byte[] DEFAULT_TEXTURE = new Primitive.TextureEntry(new UUID("89556747-24cb-43ed-920b-47caed15465f")).GetBytes();
private byte[] m_textureEntry;
@@ -104,33 +104,32 @@ namespace OpenSim.Framework
private HollowShape _hollowShape;
// Sculpted
- [XmlIgnore] private UUID _sculptTexture = UUID.Zero;
- [XmlIgnore] private byte _sculptType = (byte)0;
- [XmlIgnore] private byte[] _sculptData = new byte[0];
- [XmlIgnore] private Image _sculptBitmap = null;
+ [XmlIgnore] private UUID _sculptTexture;
+ [XmlIgnore] private byte _sculptType;
+ [XmlIgnore] private byte[] _sculptData = Utils.EmptyBytes;
// Flexi
- [XmlIgnore] private int _flexiSoftness = 0;
- [XmlIgnore] private float _flexiTension = 0f;
- [XmlIgnore] private float _flexiDrag = 0f;
- [XmlIgnore] private float _flexiGravity = 0f;
- [XmlIgnore] private float _flexiWind = 0f;
- [XmlIgnore] private float _flexiForceX = 0f;
- [XmlIgnore] private float _flexiForceY = 0f;
- [XmlIgnore] private float _flexiForceZ = 0f;
+ [XmlIgnore] private int _flexiSoftness;
+ [XmlIgnore] private float _flexiTension;
+ [XmlIgnore] private float _flexiDrag;
+ [XmlIgnore] private float _flexiGravity;
+ [XmlIgnore] private float _flexiWind;
+ [XmlIgnore] private float _flexiForceX;
+ [XmlIgnore] private float _flexiForceY;
+ [XmlIgnore] private float _flexiForceZ;
//Bright n sparkly
- [XmlIgnore] private float _lightColorR = 0f;
- [XmlIgnore] private float _lightColorG = 0f;
- [XmlIgnore] private float _lightColorB = 0f;
- [XmlIgnore] private float _lightColorA = 1f;
- [XmlIgnore] private float _lightRadius = 0f;
- [XmlIgnore] private float _lightCutoff = 0f;
- [XmlIgnore] private float _lightFalloff = 0f;
- [XmlIgnore] private float _lightIntensity = 1f;
- [XmlIgnore] private bool _flexiEntry = false;
- [XmlIgnore] private bool _lightEntry = false;
- [XmlIgnore] private bool _sculptEntry = false;
+ [XmlIgnore] private float _lightColorR;
+ [XmlIgnore] private float _lightColorG;
+ [XmlIgnore] private float _lightColorB;
+ [XmlIgnore] private float _lightColorA = 1.0f;
+ [XmlIgnore] private float _lightRadius;
+ [XmlIgnore] private float _lightCutoff;
+ [XmlIgnore] private float _lightFalloff;
+ [XmlIgnore] private float _lightIntensity = 1.0f;
+ [XmlIgnore] private bool _flexiEntry;
+ [XmlIgnore] private bool _lightEntry;
+ [XmlIgnore] private bool _sculptEntry;
public byte ProfileCurve
{
@@ -172,17 +171,11 @@ namespace OpenSim.Framework
}
}
- static PrimitiveBaseShape()
- {
- m_defaultTexture =
- new Primitive.TextureEntry(new UUID("89556747-24cb-43ed-920b-47caed15465f"));
- }
-
public PrimitiveBaseShape()
{
PCode = (byte) PCodeEnum.Primitive;
ExtraParams = new byte[1];
- Textures = m_defaultTexture;
+ m_textureEntry = DEFAULT_TEXTURE;
}
public PrimitiveBaseShape(bool noShape)
@@ -192,7 +185,7 @@ namespace OpenSim.Framework
PCode = (byte)PCodeEnum.Primitive;
ExtraParams = new byte[1];
- Textures = m_defaultTexture;
+ m_textureEntry = DEFAULT_TEXTURE;
}
[XmlIgnore]
@@ -577,15 +570,6 @@ namespace OpenSim.Framework
}
}
- public Image SculptBitmap {
- get {
- return _sculptBitmap;
- }
- set {
- _sculptBitmap = value;
- }
- }
-
public int FlexiSoftness {
get {
return _flexiSoftness;
--
cgit v1.1
From ac7ccdf7d77810aef0a3ad70f1504fdb111dc0aa Mon Sep 17 00:00:00 2001
From: John Hurliman
Date: Mon, 26 Oct 2009 14:41:27 -0700
Subject: * Changed the watchdog timer to improve the speed of UpdateThread(),
only track threads once the first call to UpdateThread() has been made, and
allow re-tracking of threads that timed out but revived later * Added a
commented out call to Watchdog.UpdateThread() in OdeScene. If it turns out
that loading a large OAR file or some other operation is timing out the
heartbeat thread, we'll need to uncomment it
---
OpenSim/Framework/Watchdog.cs | 60 +++++++++++++++++++++----------------------
1 file changed, 30 insertions(+), 30 deletions(-)
(limited to 'OpenSim/Framework')
diff --git a/OpenSim/Framework/Watchdog.cs b/OpenSim/Framework/Watchdog.cs
index b905609..5d46905 100644
--- a/OpenSim/Framework/Watchdog.cs
+++ b/OpenSim/Framework/Watchdog.cs
@@ -28,6 +28,7 @@
using System;
using System.Collections.Generic;
using System.Threading;
+using log4net;
namespace OpenSim.Framework
{
@@ -66,6 +67,7 @@ namespace OpenSim.Framework
/// stopped or has not called UpdateThread() in time
public static event WatchdogTimeout OnWatchdogTimeout;
+ private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private static Dictionary m_threads;
private static System.Timers.Timer m_watchdogTimer;
@@ -95,9 +97,6 @@ namespace OpenSim.Framework
thread.IsBackground = isBackground;
thread.Start();
- lock (m_threads)
- m_threads.Add(thread.ManagedThreadId, new ThreadWatchdogInfo(thread));
-
return thread;
}
@@ -110,24 +109,6 @@ namespace OpenSim.Framework
}
///
- /// Marks a thread as alive
- ///
- /// The ManagedThreadId of the thread to mark as
- /// alive
- public static void UpdateThread(int threadID)
- {
- ThreadWatchdogInfo threadInfo;
-
- lock (m_threads)
- {
- if (m_threads.TryGetValue(threadID, out threadInfo))
- {
- threadInfo.LastTick = Environment.TickCount & Int32.MaxValue;
- }
- }
- }
-
- ///
/// Stops watchdog tracking on the current thread
///
/// True if the thread was removed from the list of tracked
@@ -137,19 +118,38 @@ namespace OpenSim.Framework
return RemoveThread(Thread.CurrentThread.ManagedThreadId);
}
- ///
- /// Stops watchdog tracking on a thread
- ///
- /// The ManagedThreadId of the thread to stop
- /// tracking
- /// True if the thread was removed from the list of tracked
- /// threads, otherwise false
- public static bool RemoveThread(int threadID)
+ private static void AddThread(ThreadWatchdogInfo threadInfo)
+ {
+ m_log.Debug("[WATCHDOG]: Started tracking thread \"" + threadInfo.Thread.Name + "\" (ID " + threadInfo.Thread.ManagedThreadId + ")");
+
+ lock (m_threads)
+ m_threads.Add(threadInfo.Thread.ManagedThreadId, threadInfo);
+ }
+
+ private static bool RemoveThread(int threadID)
{
lock (m_threads)
return m_threads.Remove(threadID);
}
+ private static void UpdateThread(int threadID)
+ {
+ ThreadWatchdogInfo threadInfo;
+
+ // Although TryGetValue is not a thread safe operation, we use a try/catch here instead
+ // of a lock for speed. Adding/removing threads is a very rare operation compared to
+ // UpdateThread(), and a single UpdateThread() failure here and there won't break
+ // anything
+ try
+ {
+ if (m_threads.TryGetValue(threadID, out threadInfo))
+ threadInfo.LastTick = Environment.TickCount & Int32.MaxValue;
+ else
+ AddThread(new ThreadWatchdogInfo(Thread.CurrentThread));
+ }
+ catch { }
+ }
+
private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
{
WatchdogTimeout callback = OnWatchdogTimeout;
@@ -160,7 +160,7 @@ namespace OpenSim.Framework
lock (m_threads)
{
- int now = Environment.TickCount;
+ int now = Environment.TickCount & Int32.MaxValue;
foreach (ThreadWatchdogInfo threadInfo in m_threads.Values)
{
--
cgit v1.1
From 4847e62e9fd1cd473cc180220a379efba93f94a6 Mon Sep 17 00:00:00 2001
From: John Hurliman
Date: Mon, 26 Oct 2009 16:33:04 -0700
Subject: * Switched all operations on the list of clients that could be either
sync or async to use Scene.ForEachClient() instead of referencing
ClientManager directly * Added a new [Startup] config option called
use_async_when_possible to signal how to run operations that could be either
sync or async * Changed Scene.ForEachClient to respect
use_async_when_possible * Fixing a potential deadlock in Parallel.ForEach by
locking on a temporary object instead of the enumerator (which may be shared
across multiple invocations on ForEach). Thank you diva
---
OpenSim/Framework/Parallel.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
(limited to 'OpenSim/Framework')
diff --git a/OpenSim/Framework/Parallel.cs b/OpenSim/Framework/Parallel.cs
index 70eecdc..515852f 100644
--- a/OpenSim/Framework/Parallel.cs
+++ b/OpenSim/Framework/Parallel.cs
@@ -118,6 +118,7 @@ namespace OpenSim.Framework
int counter = threadCount;
AutoResetEvent threadFinishEvent = new AutoResetEvent(false);
IEnumerator enumerator = enumerable.GetEnumerator();
+ object syncRoot = new object();
Exception exception = null;
for (int i = 0; i < threadCount; i++)
@@ -131,7 +132,7 @@ namespace OpenSim.Framework
{
T entry;
- lock (enumerator)
+ lock (syncRoot)
{
if (!enumerator.MoveNext())
break;
--
cgit v1.1
From 0b1726b524934c2020aaf2b1f130219fb87003fd Mon Sep 17 00:00:00 2001
From: John Hurliman
Date: Mon, 26 Oct 2009 16:48:43 -0700
Subject: Removing the ClientManager reference from IScene and hiding it
entirely inside Scene as an implementation detail. This will reduce
programming error and make it easier to refactor the avatar vs client vs
presence mess later on
---
OpenSim/Framework/IScene.cs | 1 -
1 file changed, 1 deletion(-)
(limited to 'OpenSim/Framework')
diff --git a/OpenSim/Framework/IScene.cs b/OpenSim/Framework/IScene.cs
index f34027d..8067052 100644
--- a/OpenSim/Framework/IScene.cs
+++ b/OpenSim/Framework/IScene.cs
@@ -62,7 +62,6 @@ namespace OpenSim.Framework
RegionInfo RegionInfo { get; }
RegionStatus RegionStatus { get; set; }
- ClientManager ClientManager { get; }
IConfigSource Config { get; }
float TimeDilation { get; }
--
cgit v1.1
From c75d4156487b35aac47aa6818144862a99bb841c Mon Sep 17 00:00:00 2001
From: John Hurliman
Date: Tue, 27 Oct 2009 00:26:56 -0700
Subject: * Converts ClientManager.ForEach() (and as a result,
Scene.ForEachClient()) to use a non-blocking parallel method when operating
in async mode * Minor code readability cleanup
---
OpenSim/Framework/ClientManager.cs | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
(limited to 'OpenSim/Framework')
diff --git a/OpenSim/Framework/ClientManager.cs b/OpenSim/Framework/ClientManager.cs
index 61b59e7..baff2f4 100644
--- a/OpenSim/Framework/ClientManager.cs
+++ b/OpenSim/Framework/ClientManager.cs
@@ -204,7 +204,10 @@ namespace OpenSim.Framework
public void ForEach(Action action)
{
IClientAPI[] localArray = m_array;
- Parallel.ForEach(localArray, action);
+ Parallel.For(0, localArray.Length,
+ delegate(int i)
+ { action(localArray[i]); }
+ );
}
///
--
cgit v1.1