Merge branch 'master' of /home/opensim/var/repo/opensim

integration
BlueWall 2012-06-07 06:48:48 -04:00
commit 860cf767a1
10 changed files with 378 additions and 257 deletions

View File

@ -66,6 +66,7 @@ namespace OpenSim.Framework.Servers.HttpServer
ThreadPriority.Normal,
false,
true,
null,
int.MaxValue);
}
@ -75,6 +76,7 @@ namespace OpenSim.Framework.Servers.HttpServer
ThreadPriority.Normal,
false,
true,
null,
1000 * 60 * 10);
}

View File

@ -42,7 +42,7 @@ namespace OpenSim.Framework
const double WATCHDOG_INTERVAL_MS = 2500.0d;
/// <summary>Maximum timeout in milliseconds before a thread is considered dead</summary>
const int WATCHDOG_TIMEOUT_MS = 5000;
public const int WATCHDOG_TIMEOUT_MS = 5000;
[System.Diagnostics.DebuggerDisplay("{Thread.Name}")]
public class ThreadWatchdogInfo
@ -58,7 +58,7 @@ namespace OpenSim.Framework
public int FirstTick { get; private set; }
/// <summary>
/// First time this heartbeat update was invoked
/// Last time this heartbeat update was invoked
/// </summary>
public int LastTick { get; set; }
@ -77,6 +77,11 @@ namespace OpenSim.Framework
/// </summary>
public bool AlarmIfTimeout { get; set; }
/// <summary>
/// Method execute if alarm goes off. If null then no alarm method is fired.
/// </summary>
public Func<string> AlarmMethod { get; set; }
public ThreadWatchdogInfo(Thread thread, int timeout)
{
Thread = thread;
@ -87,16 +92,10 @@ namespace OpenSim.Framework
}
/// <summary>
/// This event is called whenever a tracked thread is stopped or
/// has not called UpdateThread() in time
/// </summary>
/// <param name="thread">The thread that has been identified as dead</param>
/// <param name="lastTick">The last time this thread called UpdateThread()</param>
public delegate void WatchdogTimeout(Thread thread, int lastTick);
/// <summary>This event is called whenever a tracked thread is
/// stopped or has not called UpdateThread() in time</summary>
public static event WatchdogTimeout OnWatchdogTimeout;
/// This event is called whenever a tracked thread is
/// stopped or has not called UpdateThread() in time<
/// /summary>
public static event Action<ThreadWatchdogInfo> OnWatchdogTimeout;
private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private static Dictionary<int, ThreadWatchdogInfo> m_threads;
@ -123,7 +122,7 @@ namespace OpenSim.Framework
public static Thread StartThread(
ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout)
{
return StartThread(start, name, priority, isBackground, alarmIfTimeout, WATCHDOG_TIMEOUT_MS);
return StartThread(start, name, priority, isBackground, alarmIfTimeout, null, WATCHDOG_TIMEOUT_MS);
}
/// <summary>
@ -135,17 +134,24 @@ namespace OpenSim.Framework
/// <param name="isBackground">True to run this thread as a background
/// thread, otherwise false</param>
/// <param name="alarmIfTimeout">Trigger an alarm function is we have timed out</param>
/// <param name="alarmMethod">
/// Alarm method to call if alarmIfTimeout is true and there is a timeout.
/// Normally, this will just return some useful debugging information.
/// </param>
/// <param name="timeout">Number of milliseconds to wait until we issue a warning about timeout.</param>
/// <returns>The newly created Thread object</returns>
public static Thread StartThread(
ThreadStart start, string name, ThreadPriority priority, bool isBackground, bool alarmIfTimeout, int timeout)
ThreadStart start, string name, ThreadPriority priority, bool isBackground,
bool alarmIfTimeout, Func<string> alarmMethod, int timeout)
{
Thread thread = new Thread(start);
thread.Name = name;
thread.Priority = priority;
thread.IsBackground = isBackground;
ThreadWatchdogInfo twi = new ThreadWatchdogInfo(thread, timeout) { AlarmIfTimeout = alarmIfTimeout };
ThreadWatchdogInfo twi
= new ThreadWatchdogInfo(thread, timeout)
{ AlarmIfTimeout = alarmIfTimeout, AlarmMethod = alarmMethod };
m_log.DebugFormat(
"[WATCHDOG]: Started tracking thread {0}, ID {1}", twi.Thread.Name, twi.Thread.ManagedThreadId);
@ -258,7 +264,7 @@ namespace OpenSim.Framework
/// <param name="e"></param>
private static void WatchdogTimerElapsed(object sender, System.Timers.ElapsedEventArgs e)
{
WatchdogTimeout callback = OnWatchdogTimeout;
Action<ThreadWatchdogInfo> callback = OnWatchdogTimeout;
if (callback != null)
{
@ -296,7 +302,7 @@ namespace OpenSim.Framework
if (callbackInfos != null)
foreach (ThreadWatchdogInfo callbackInfo in callbackInfos)
callback(callbackInfo.Thread, callbackInfo.LastTick);
callback(callbackInfo);
}
m_watchdogTimer.Start();

View File

@ -438,12 +438,16 @@ namespace OpenSim
}
}
private void WatchdogTimeoutHandler(System.Threading.Thread thread, int lastTick)
private void WatchdogTimeoutHandler(Watchdog.ThreadWatchdogInfo twi)
{
int now = Environment.TickCount & Int32.MaxValue;
m_log.ErrorFormat("[WATCHDOG]: Timeout detected for thread \"{0}\". ThreadState={1}. Last tick was {2}ms ago",
thread.Name, thread.ThreadState, now - lastTick);
m_log.ErrorFormat(
"[WATCHDOG]: Timeout detected for thread \"{0}\". ThreadState={1}. Last tick was {2}ms ago. {3}",
twi.Thread.Name,
twi.Thread.ThreadState,
now - twi.LastTick,
twi.AlarmMethod != null ? string.Format("Data: {0}", twi.AlarmMethod()) : "");
}
#region Console Commands

View File

@ -163,6 +163,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private int m_malformedCount = 0; // Guard against a spamming attack
/// <summary>
/// Record current outgoing client for monitoring purposes.
/// </summary>
private IClientAPI m_currentOutgoingClient;
/// <summary>
/// Recording current incoming client for monitoring purposes.
/// </summary>
private IClientAPI m_currentIncomingClient;
public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager)
: base(listenIP, (int)port)
{
@ -244,19 +254,56 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (m_scene == null)
throw new InvalidOperationException("[LLUDPSERVER]: Cannot LLUDPServer.Start() without an IScene reference");
m_log.Info("[LLUDPSERVER]: Starting the LLUDP server in " + (m_asyncPacketHandling ? "asynchronous" : "synchronous") + " mode");
m_log.InfoFormat(
"[LLUDPSERVER]: Starting the LLUDP server in {0} mode",
m_asyncPacketHandling ? "asynchronous" : "synchronous");
base.Start(m_recvBufferSize, m_asyncPacketHandling);
// Start the packet processing threads
Watchdog.StartThread(
IncomingPacketHandler, "Incoming Packets (" + m_scene.RegionInfo.RegionName + ")", ThreadPriority.Normal, false, true);
IncomingPacketHandler,
string.Format("Incoming Packets ({0})", m_scene.RegionInfo.RegionName),
ThreadPriority.Normal,
false,
true,
GetWatchdogIncomingAlarmData,
Watchdog.WATCHDOG_TIMEOUT_MS);
Watchdog.StartThread(
OutgoingPacketHandler, "Outgoing Packets (" + m_scene.RegionInfo.RegionName + ")", ThreadPriority.Normal, false, true);
OutgoingPacketHandler,
string.Format("Outgoing Packets ({0})", m_scene.RegionInfo.RegionName),
ThreadPriority.Normal,
false,
true,
GetWatchdogOutgoingAlarmData,
Watchdog.WATCHDOG_TIMEOUT_MS);
m_elapsedMSSinceLastStatReport = Environment.TickCount;
}
/// <summary>
/// If the outgoing UDP thread times out, then return client that was being processed to help with debugging.
/// </summary>
/// <returns></returns>
private string GetWatchdogIncomingAlarmData()
{
return string.Format(
"Client is {0}",
m_currentIncomingClient != null ? m_currentIncomingClient.Name : "none");
}
/// <summary>
/// If the outgoing UDP thread times out, then return client that was being processed to help with debugging.
/// </summary>
/// <returns></returns>
private string GetWatchdogOutgoingAlarmData()
{
return string.Format(
"Client is {0}",
m_currentOutgoingClient != null ? m_currentOutgoingClient.Name : "none");
}
public new void Stop()
{
m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName);
@ -1067,6 +1114,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
client.IsLoggingOut = true;
client.Close();
}
else
{
m_log.WarnFormat(
"[LLUDPSERVER]: Tried to remove client with id {0} but not such client in {1}",
udpClient.AgentID, m_scene.RegionInfo.RegionName);
}
}
private void IncomingPacketHandler()
@ -1173,6 +1226,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// client. m_packetSent will be set to true if a packet is sent
m_scene.ForEachClient(clientPacketHandler);
m_currentOutgoingClient = null;
// If nothing was sent, sleep for the minimum amount of time before a
// token bucket could get more tokens
if (!m_packetSent)
@ -1191,6 +1246,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private void ClientOutgoingPacketHandler(IClientAPI client)
{
m_currentOutgoingClient = client;
try
{
if (client is LLClientView)
@ -1216,8 +1273,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
catch (Exception ex)
{
m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler iteration for " + client.Name +
" threw an exception: " + ex.Message, ex);
m_log.Error(
string.Format("[LLUDPSERVER]: OutgoingPacketHandler iteration for {0} threw ", client.Name), ex);
}
}
@ -1243,6 +1300,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
nticks++;
watch1.Start();
m_currentOutgoingClient = client;
try
{
if (client is LLClientView)
@ -1344,6 +1403,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Make sure this client is still alive
if (m_scene.TryGetClient(udpClient.AgentID, out client))
{
m_currentIncomingClient = client;
try
{
// Process this packet
@ -1361,6 +1422,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_log.ErrorFormat("[LLUDPSERVER]: Client packet handler for {0} for packet {1} threw an exception", udpClient.AgentID, packet.Type);
m_log.Error(e.Message, e);
}
finally
{
m_currentIncomingClient = null;
}
}
else
{

View File

@ -73,7 +73,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
"set terrain heights <corner> <min> <max> [<x>] [<y>]",
"Sets the terrain texture heights on corner #<corner> to <min>/<max>, if <x> or <y> are specified, it will only " +
"set it on regions with a matching coordinate. Specify -1 in <x> or <y> to wildcard" +
" that coordinate. Corner # SW = 0, NW = 1, SE = 2, NE = 3.",
" that coordinate. Corner # SW = 0, NW = 1, SE = 2, NE = 3, all corners = -1.",
consoleSetTerrainHeights);
m_module.Scene.AddCommand(
@ -143,6 +143,16 @@ namespace OpenSim.Region.CoreModules.World.Estate
switch (corner)
{
case -1:
m_module.Scene.RegionInfo.RegionSettings.Elevation1SW = lowValue;
m_module.Scene.RegionInfo.RegionSettings.Elevation2SW = highValue;
m_module.Scene.RegionInfo.RegionSettings.Elevation1NW = lowValue;
m_module.Scene.RegionInfo.RegionSettings.Elevation2NW = highValue;
m_module.Scene.RegionInfo.RegionSettings.Elevation1SE = lowValue;
m_module.Scene.RegionInfo.RegionSettings.Elevation2SE = highValue;
m_module.Scene.RegionInfo.RegionSettings.Elevation1NE = lowValue;
m_module.Scene.RegionInfo.RegionSettings.Elevation2NE = highValue;
break;
case 0:
m_module.Scene.RegionInfo.RegionSettings.Elevation1SW = lowValue;
m_module.Scene.RegionInfo.RegionSettings.Elevation2SW = highValue;

View File

@ -178,8 +178,6 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders
// int sztmp = bs.ReadInt16() + 1;
// fileWidth = sztmp;
// fileHeight = sztmp;
bs.ReadInt16();
bs.ReadInt16();
bs.ReadInt16();
bs.ReadInt16();
break;

View File

@ -84,7 +84,11 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
Debug.Assert(heightRanges.Length == 4);
Bitmap[] detailTexture = new Bitmap[4];
Bitmap output = null;
BitmapData outputData = null;
try
{
if (textureTerrain)
{
// Swap empty terrain textureIDs with default IDs
@ -138,7 +142,12 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
// Make sure this texture is the correct size, otherwise resize
if (bitmap.Width != 256 || bitmap.Height != 256)
bitmap = ImageUtils.ResizeImage(bitmap, 256, 256);
{
using (Bitmap origBitmap = bitmap)
{
bitmap = ImageUtils.ResizeImage(origBitmap, 256, 256);
}
}
// Save the decoded and resized texture to the cache
byte[] data;
@ -241,8 +250,8 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
#region Texture Compositing
Bitmap output = new Bitmap(256, 256, PixelFormat.Format24bppRgb);
BitmapData outputData = output.LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
output = new Bitmap(256, 256, PixelFormat.Format24bppRgb);
outputData = output.LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
unsafe
{
@ -297,6 +306,13 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
for (int i = 0; i < 4; i++)
detailTexture[i].UnlockBits(datas[i]);
}
}
finally
{
for (int i = 0; i < 4; i++)
if (detailTexture[i] != null)
detailTexture[i].Dispose();
}
output.UnlockBits(outputData);

View File

@ -54,8 +54,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
private static readonly UUID TEXTURE_METADATA_MAGIC = new UUID("802dc0e0-f080-4931-8b57-d1be8611c4f3");
private static readonly Color4 WATER_COLOR = new Color4(29, 72, 96, 216);
private static readonly ILog m_log =
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private Scene m_scene;
private IRendering m_primMesher;
@ -88,11 +87,11 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
if (renderers.Count > 0)
{
m_primMesher = RenderingLoader.LoadRenderer(renderers[0]);
m_log.Debug("[MAPTILE]: Loaded prim mesher " + m_primMesher.ToString());
m_log.DebugFormat("[WARP 3D IMAGE MODULE]: Loaded prim mesher {0}", m_primMesher);
}
else
{
m_log.Debug("[MAPTILE]: No prim mesher loaded, prim rendering will be disabled");
m_log.Debug("[WARP 3D IMAGE MODULE]: No prim mesher loaded, prim rendering will be disabled");
}
m_scene.RegisterModuleInterface<IMapImageGenerator>(this);
@ -150,7 +149,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
}
catch
{
m_log.Warn("[MAPTILE]: Failed to load StartupConfig");
m_log.Warn("[WARP 3D IMAGE MODULE]: Failed to load StartupConfig");
}
m_colors.Clear();
@ -204,7 +203,10 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
Bitmap bitmap = renderer.Scene.getImage();
if (m_useAntiAliasing)
bitmap = ImageUtils.ResizeImage(bitmap, viewport.Width, viewport.Height);
{
using (Bitmap origBitmap = bitmap)
bitmap = ImageUtils.ResizeImage(origBitmap, viewport.Width, viewport.Height);
}
return bitmap;
}
@ -219,7 +221,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
catch (Exception e)
{
// JPEG2000 encoder failed
m_log.Error("[MAPTILE]: Failed generating terrain map: " + e);
m_log.Error("[WARP 3D IMAGE MODULE]: Failed generating terrain map: ", e);
}
return null;
@ -318,8 +320,17 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
uint globalX, globalY;
Utils.LongToUInts(m_scene.RegionInfo.RegionHandle, out globalX, out globalY);
Bitmap image = TerrainSplat.Splat(heightmap, textureIDs, startHeights, heightRanges, new Vector3d(globalX, globalY, 0.0), m_scene.AssetService, textureTerrain);
warp_Texture texture = new warp_Texture(image);
warp_Texture texture;
using (
Bitmap image
= TerrainSplat.Splat(
heightmap, textureIDs, startHeights, heightRanges,
new Vector3d(globalX, globalY, 0.0), m_scene.AssetService, textureTerrain))
{
texture = new warp_Texture(image);
}
warp_Material material = new warp_Material(texture);
material.setReflectivity(50);
renderer.Scene.addMaterial("TerrainColor", material);
@ -546,12 +557,15 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
{
try
{
Bitmap bitmap = (Bitmap)J2kImage.FromStream(stream);
int pixelBytes;
using (Bitmap bitmap = (Bitmap)J2kImage.FromStream(stream))
{
width = bitmap.Width;
height = bitmap.Height;
BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, bitmap.PixelFormat);
int pixelBytes = (bitmap.PixelFormat == PixelFormat.Format24bppRgb) ? 3 : 4;
pixelBytes = (bitmap.PixelFormat == PixelFormat.Format24bppRgb) ? 3 : 4;
// Sum up the individual channels
unsafe
@ -586,6 +600,7 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
}
}
}
}
// Get the averages for each channel
const decimal OO_255 = 1m / 255m;
@ -603,7 +618,10 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
}
catch (Exception ex)
{
m_log.WarnFormat("[MAPTILE]: Error decoding JPEG2000 texture {0} ({1} bytes): {2}", textureID, j2kData.Length, ex.Message);
m_log.WarnFormat(
"[WARP 3D IMAGE MODULE]: Error decoding JPEG2000 texture {0} ({1} bytes): {2}",
textureID, j2kData.Length, ex.Message);
width = 0;
height = 0;
return new Color4(0.5f, 0.5f, 0.5f, 1.0f);

View File

@ -1343,14 +1343,14 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
if (terrain == null)
return;
m_log.DebugFormat("[WORLDMAP]: Generating map image for {0}", m_scene.RegionInfo.RegionName);
byte[] data = terrain.WriteJpeg2000Image();
if (data == null)
return;
byte[] overlay = GenerateOverlay();
m_log.Debug("[WORLDMAP]: STORING MAPTILE IMAGE");
UUID terrainImageID = UUID.Random();
UUID parcelImageID = UUID.Zero;
@ -1365,7 +1365,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap
asset.Flags = AssetFlags.Maptile;
// Store the new one
m_log.DebugFormat("[WORLDMAP]: Storing map tile {0}", asset.ID);
m_log.DebugFormat("[WORLDMAP]: Storing map tile {0} for {1}", asset.ID, m_scene.RegionInfo.RegionName);
m_scene.AssetService.Store(asset);
if (overlay != null)

View File

@ -113,14 +113,15 @@ namespace OpenSim.Region.OptionalModules.World.WorldView
if (!m_Enabled)
return new Byte[0];
Bitmap bmp = m_Generator.CreateViewImage(pos, rot, fov, width,
height, usetex);
MemoryStream str = new MemoryStream();
using (Bitmap bmp = m_Generator.CreateViewImage(pos, rot, fov, width, height, usetex))
{
using (MemoryStream str = new MemoryStream())
{
bmp.Save(str, ImageFormat.Jpeg);
return str.ToArray();
}
}
}
}
}