From dd0556abc9a88121ac91cd86c60a51aac9c726e5 Mon Sep 17 00:00:00 2001
From: Melanie
Date: Sun, 19 Aug 2012 22:05:38 +0100
Subject: Fix llDialog responses so that they can be heard throughout the
region. This now conforms to the behaviour in SL.
---
OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 01ceeed..22b3d35 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -5810,7 +5810,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
args.Channel = ch;
args.From = String.Empty;
args.Message = Utils.BytesToString(msg);
- args.Type = ChatTypeEnum.Shout;
+ args.Type = ChatTypeEnum.Region; //Behaviour in SL is that the response can be heard from any distance
args.Position = new Vector3();
args.Scene = Scene;
args.Sender = this;
--
cgit v1.1
From bcbd450fe441e94d6c0f547055b4e95f75a5b0d0 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 20 Aug 2012 20:24:54 +0100
Subject: Add --force flag to "kick user" console command to allow bypassing of
recent race condition checks.
This is to allow a second attempt to remove an avatar even if "show connections" shows them as already inactive (i.e. close has already been attempted once).
You should only attempt --force if a normal kick fails.
This is partly for diagnostics as we have seen some connections occasionally remain on lbsa plaza even if they are registered as inactive.
This is not a permanent solution and may not work anyway - the ultimate solution is to stop this problem from happening in the first place.
---
.../Linden/Caps/EventQueue/Tests/EventQueueTests.cs | 2 +-
OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 14 +++++++++-----
2 files changed, 10 insertions(+), 6 deletions(-)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
index cd70410..d604cf6 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
@@ -94,7 +94,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
UUID spId = TestHelpers.ParseTail(0x1);
SceneHelpers.AddScenePresence(m_scene, spId);
- m_scene.IncomingCloseAgent(spId);
+ m_scene.IncomingCloseAgent(spId, false);
// TODO: Add more assertions for the other aspects of event queues
Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0));
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 22b3d35..148d0e0 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -487,16 +487,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#region Client Methods
- ///
- /// Close down the client view
- ///
public void Close()
{
+ Close(false);
+ }
+
+ public void Close(bool force)
+ {
// We lock here to prevent race conditions between two threads calling close simultaneously (e.g.
// a simultaneous relog just as a client is being closed out due to no packet ack from the old connection.
lock (CloseSyncLock)
{
- if (!IsActive)
+ // We still perform a force close inside the sync lock since this is intended to attempt close where
+ // there is some unidentified connection problem, not where we have issues due to deadlock
+ if (!IsActive && !force)
return;
IsActive = false;
@@ -11989,7 +11993,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
Kick(reason);
Thread.Sleep(1000);
- Close();
+ Disconnect();
}
public void Disconnect()
--
cgit v1.1
From 68814f904e1f0c5be961791f3f475dcda4a88248 Mon Sep 17 00:00:00 2001
From: Melanie
Date: Fri, 31 Aug 2012 00:37:27 +0100
Subject: Replace SendBannedUserList with Avination's version. Untested in
core. Not even test compiled.
---
.../Region/ClientStack/Linden/UDP/LLClientView.cs | 57 ++++++++++++----------
1 file changed, 32 insertions(+), 25 deletions(-)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 148d0e0..d05ffea 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -4451,37 +4451,44 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (bl[i].BannedUserID == UUID.Zero)
continue;
BannedUsers.Add(bl[i].BannedUserID);
- }
- EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
- packet.AgentData.TransactionID = UUID.Random();
- packet.AgentData.AgentID = AgentId;
- packet.AgentData.SessionID = SessionId;
- packet.MethodData.Invoice = invoice;
- packet.MethodData.Method = Utils.StringToBytes("setaccess");
+ if (BannedUsers.Count >= 50 || (i == (bl.Length - 1) && BannedUsers.Count > 0))
+ {
+ EstateOwnerMessagePacket packet = new EstateOwnerMessagePacket();
+ packet.AgentData.TransactionID = UUID.Random();
+ packet.AgentData.AgentID = AgentId;
+ packet.AgentData.SessionID = SessionId;
+ packet.MethodData.Invoice = invoice;
+ packet.MethodData.Method = Utils.StringToBytes("setaccess");
- EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
+ EstateOwnerMessagePacket.ParamListBlock[] returnblock = new EstateOwnerMessagePacket.ParamListBlock[6 + BannedUsers.Count];
- for (int i = 0; i < (6 + BannedUsers.Count); i++)
- {
- returnblock[i] = new EstateOwnerMessagePacket.ParamListBlock();
- }
- int j = 0;
+ int j;
+ for (j = 0; j < (6 + BannedUsers.Count); j++)
+ {
+ returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
+ }
+ j = 0;
- returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
- returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
- returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
- returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
- returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
- returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
+ returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
+ returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
+ returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
+ returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
+ returnblock[j].Parameter = Utils.StringToBytes(BannedUsers.Count.ToString()); j++;
+ returnblock[j].Parameter = Utils.StringToBytes("0"); j++;
- foreach (UUID banned in BannedUsers)
- {
- returnblock[j].Parameter = banned.GetBytes(); j++;
+ foreach (UUID banned in BannedUsers)
+ {
+ returnblock[j].Parameter = banned.GetBytes(); j++;
+ }
+ packet.ParamList = returnblock;
+ packet.Header.Reliable = true;
+ OutPacket(packet, ThrottleOutPacketType.Task);
+
+ BannedUsers.Clear();
+ }
}
- packet.ParamList = returnblock;
- packet.Header.Reliable = false;
- OutPacket(packet, ThrottleOutPacketType.Task);
+
}
public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
--
cgit v1.1
From f0178a6a413e35a45efcb0f7f0eeffc0daed15fe Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 5 Oct 2012 01:12:56 +0100
Subject: refactor: Move OpenSim.Framework.PacketPool to
OpenSim.Region.Clientstack.Linden.UDP
This is to allow it to use OpenSim.Framework.Monitoring in the future.
This is also a better location since the packet pool is linden udp specific
---
.../Region/ClientStack/Linden/UDP/PacketPool.cs | 249 +++++++++++++++++++++
1 file changed, 249 insertions(+)
create mode 100644 OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
new file mode 100644
index 0000000..fc9406b
--- /dev/null
+++ b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
@@ -0,0 +1,249 @@
+/*
+ * 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.Collections.Generic;
+using System.Reflection;
+using OpenMetaverse;
+using OpenMetaverse.Packets;
+using log4net;
+
+namespace OpenSim.Region.ClientStack.LindenUDP
+{
+ public sealed class PacketPool
+ {
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ private static readonly PacketPool instance = new PacketPool();
+
+ private bool packetPoolEnabled = true;
+ private bool dataBlockPoolEnabled = true;
+
+ ///
+ /// Pool of packets available for reuse.
+ ///
+ private readonly Dictionary> pool = new Dictionary>();
+
+ private static Dictionary> DataBlocks =
+ new Dictionary>();
+
+ static PacketPool()
+ {
+ }
+
+ public static PacketPool Instance
+ {
+ get { return instance; }
+ }
+
+ public bool RecyclePackets
+ {
+ set { packetPoolEnabled = value; }
+ get { return packetPoolEnabled; }
+ }
+
+ public bool RecycleDataBlocks
+ {
+ set { dataBlockPoolEnabled = value; }
+ get { return dataBlockPoolEnabled; }
+ }
+
+ public Packet GetPacket(PacketType type)
+ {
+ Packet packet;
+
+ if (!packetPoolEnabled)
+ return Packet.BuildPacket(type);
+
+ lock (pool)
+ {
+ if (!pool.ContainsKey(type) || pool[type] == null || (pool[type]).Count == 0)
+ {
+ // Creating a new packet if we cannot reuse an old package
+ packet = Packet.BuildPacket(type);
+ }
+ else
+ {
+ // Recycle old packages
+ packet = (pool[type]).Pop();
+ }
+ }
+
+ return packet;
+ }
+
+ // private byte[] decoded_header = new byte[10];
+ private static PacketType GetType(byte[] bytes)
+ {
+ byte[] decoded_header = new byte[10 + 8];
+ ushort id;
+ PacketFrequency freq;
+
+ if ((bytes[0] & Helpers.MSG_ZEROCODED) != 0)
+ {
+ Helpers.ZeroDecode(bytes, 16, decoded_header);
+ }
+ else
+ {
+ Buffer.BlockCopy(bytes, 0, decoded_header, 0, 10);
+ }
+
+ if (decoded_header[6] == 0xFF)
+ {
+ if (decoded_header[7] == 0xFF)
+ {
+ id = (ushort) ((decoded_header[8] << 8) + decoded_header[9]);
+ freq = PacketFrequency.Low;
+ }
+ else
+ {
+ id = decoded_header[7];
+ freq = PacketFrequency.Medium;
+ }
+ }
+ else
+ {
+ id = decoded_header[6];
+ freq = PacketFrequency.High;
+ }
+
+ return Packet.GetType(id, freq);
+ }
+
+ public Packet GetPacket(byte[] bytes, ref int packetEnd, byte[] zeroBuffer)
+ {
+ PacketType type = GetType(bytes);
+
+ Array.Clear(zeroBuffer, 0, zeroBuffer.Length);
+
+ int i = 0;
+ Packet packet = GetPacket(type);
+ if (packet == null)
+ m_log.WarnFormat("[PACKETPOOL]: Failed to get packet of type {0}", type);
+ else
+ packet.FromBytes(bytes, ref i, ref packetEnd, zeroBuffer);
+
+ return packet;
+ }
+
+ ///
+ /// Return a packet to the packet pool
+ ///
+ ///
+ public void ReturnPacket(Packet packet)
+ {
+ if (dataBlockPoolEnabled)
+ {
+ switch (packet.Type)
+ {
+ case PacketType.ObjectUpdate:
+ ObjectUpdatePacket oup = (ObjectUpdatePacket)packet;
+
+ foreach (ObjectUpdatePacket.ObjectDataBlock oupod in oup.ObjectData)
+ ReturnDataBlock(oupod);
+
+ oup.ObjectData = null;
+ break;
+
+ case PacketType.ImprovedTerseObjectUpdate:
+ ImprovedTerseObjectUpdatePacket itoup = (ImprovedTerseObjectUpdatePacket)packet;
+
+ foreach (ImprovedTerseObjectUpdatePacket.ObjectDataBlock itoupod in itoup.ObjectData)
+ ReturnDataBlock(itoupod);
+
+ itoup.ObjectData = null;
+ break;
+ }
+ }
+
+ if (packetPoolEnabled)
+ {
+ switch (packet.Type)
+ {
+ // List pooling packets here
+ case PacketType.PacketAck:
+ case PacketType.ObjectUpdate:
+ case PacketType.ImprovedTerseObjectUpdate:
+ lock (pool)
+ {
+ PacketType type = packet.Type;
+
+ if (!pool.ContainsKey(type))
+ {
+ pool[type] = new Stack();
+ }
+
+ if ((pool[type]).Count < 50)
+ {
+ (pool[type]).Push(packet);
+ }
+ }
+ break;
+
+ // Other packets wont pool
+ default:
+ return;
+ }
+ }
+ }
+
+ public static T GetDataBlock() where T: new()
+ {
+ lock (DataBlocks)
+ {
+ Stack s;
+
+ if (DataBlocks.TryGetValue(typeof(T), out s))
+ {
+ if (s.Count > 0)
+ return (T)s.Pop();
+ }
+ else
+ {
+ DataBlocks[typeof(T)] = new Stack();
+ }
+
+ return new T();
+ }
+ }
+
+ public static void ReturnDataBlock(T block) where T: new()
+ {
+ if (block == null)
+ return;
+
+ lock (DataBlocks)
+ {
+ if (!DataBlocks.ContainsKey(typeof(T)))
+ DataBlocks[typeof(T)] = new Stack();
+
+ if (DataBlocks[typeof(T)].Count < 50)
+ DataBlocks[typeof(T)].Push(block);
+ }
+ }
+ }
+}
\ No newline at end of file
--
cgit v1.1
From 7c7cdf3431c1c8ee1575779f96980ac1d0de6be8 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 5 Oct 2012 01:43:29 +0100
Subject: Read PacketPool config in LLUDPServer with other config params rather
than in Scene.
This is to resolve previous build break.
This unnecessarily but harmlessly reads and sets the parameter multiple times - scene was doing the same thing.
---
OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 9 +++++++++
1 file changed, 9 insertions(+)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 55780d6..d11fcbf 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -222,6 +222,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_pausedAckTimeout = 1000 * 300; // 5 minutes
}
+ // FIXME: This actually only needs to be done once since the PacketPool is shared across all servers.
+ // However, there is no harm in temporarily doing it multiple times.
+ IConfig packetConfig = configSource.Configs["PacketPool"];
+ if (packetConfig != null)
+ {
+ PacketPool.Instance.RecyclePackets = packetConfig.GetBoolean("RecyclePackets", true);
+ PacketPool.Instance.RecycleDataBlocks = packetConfig.GetBoolean("RecycleDataBlocks", true);
+ }
+
#region BinaryStats
config = configSource.Configs["Statistics.Binary"];
m_shouldCollectStats = false;
--
cgit v1.1
From 16c9c1dff7bbf299efddd44e4f9aeeb7db38fff6 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Sat, 6 Oct 2012 02:34:49 +0100
Subject: On receiving TaskInventoryAccepted with a destination folder in the
binary bucket slot for RLV, notify the viewer about inventory folder updates.
The viewer would not see the folder move without this, either on accept or decline.
This commit also updates the TaskInventoryOffered message to better conform with the data LL uses
Changes are, agentID is prim owner rather than prim id, agent name is now simply object name rather than name with owner detail,
message is just folder name in single quotes, message is not timestamped.
However, folder is not renamed "still #RLV/~". Long term solution is probably not to do these operations server-side.
Notes will be added to http://opensimulator.org/mantis/view.php?id=6311
---
OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index d05ffea..0869bd5 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -5862,7 +5862,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
msgpack.MessageBlock.ID,
msgpack.MessageBlock.Offline != 0 ? true : false,
msgpack.MessageBlock.Position,
- msgpack.MessageBlock.BinaryBucket);
+ msgpack.MessageBlock.BinaryBucket,
+ true);
handlerInstantMessage(this, im);
}
--
cgit v1.1
From 73c9abf5f2e2017bf924d6183502e337d28a7232 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 9 Oct 2012 01:35:27 +0100
Subject: Move OpenSim.Data.RegionFlags -> OpenSim.Framework.RegionFlags to
make it easier for other code to use (e.g. LSL_Api) without having to
reference OpenSim.Data just for this.
---
OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 1 +
1 file changed, 1 insertion(+)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 0869bd5..62f51d9 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -47,6 +47,7 @@ using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using Timer = System.Timers.Timer;
using AssetLandmark = OpenSim.Framework.AssetLandmark;
+using RegionFlags = OpenMetaverse.RegionFlags;
using Nini.Config;
using System.IO;
--
cgit v1.1
From e76b01a201a9b2d45b56cd5dc2a207b08b4529e5 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 10 Oct 2012 00:26:43 +0100
Subject: Lock on AgentCircuitData during Scene.AddClient() and RemoveClient()
to prevent an inactive connection being left behind if the user closes the
viewer whilst the connection is being established.
This should remove the need to run the console command "kick user --force" when these connections are left around.
---
.../Linden/Caps/EventQueue/EventQueueGetModule.cs | 13 ++-----------
OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 14 +++++++-------
2 files changed, 9 insertions(+), 18 deletions(-)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
index 594b229..0dd0904 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
@@ -94,7 +94,7 @@ namespace OpenSim.Region.ClientStack.Linden
//scene.CommsManager.HttpServer.AddLLSDHandler("/CAPS/EQG/", EventQueueFallBack);
- scene.EventManager.OnNewClient += OnNewClient;
+// scene.EventManager.OnNewClient += OnNewClient;
// TODO: Leaving these open, or closing them when we
// become a child is incorrect. It messes up TP in a big
@@ -102,6 +102,7 @@ namespace OpenSim.Region.ClientStack.Linden
// circuit is there.
scene.EventManager.OnClientClosed += ClientClosed;
+
scene.EventManager.OnMakeChildAgent += MakeChildAgent;
scene.EventManager.OnRegisterCaps += OnRegisterCaps;
@@ -226,16 +227,6 @@ namespace OpenSim.Region.ClientStack.Linden
#endregion
- private void OnNewClient(IClientAPI client)
- {
- //client.OnLogout += ClientClosed;
- }
-
-// private void ClientClosed(IClientAPI client)
-// {
-// ClientClosed(client.AgentId);
-// }
-
private void ClientClosed(UUID agentID, Scene scene)
{
// m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index d11fcbf..ab670a7 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -1103,20 +1103,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
IClientAPI client = null;
- // In priciple there shouldn't be more than one thread here, ever.
- // But in case that happens, we need to synchronize this piece of code
- // because it's too important
- lock (this)
+ // We currently synchronize this code across the whole scene to avoid issues such as
+ // http://opensimulator.org/mantis/view.php?id=5365 However, once locking per agent circuit can be done
+ // consistently, this lock could probably be removed.
+ lock (this)
{
if (!m_scene.TryGetClient(agentID, out client))
{
LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO);
-
+
client = new LLClientView(m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
client.OnLogout += LogoutHandler;
-
+
((LLClientView)client).DisableFacelights = m_disableFacelights;
-
+
client.Start();
}
}
--
cgit v1.1
From 1f2472d0fcd86a7ae09c01ecb3508eab001ce033 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 11 Oct 2012 23:28:53 +0100
Subject: Extend "show stats" command to "show stats [list|all|]"
This allows different categories of stats to be shown, with options to list categories or show all stats.
Currently categories are scene and simulator and only a very few stats are currently registered via this mechanism.
This commit also adds percentage stats for packets and blocks reused from the packet pool.
---
.../Region/ClientStack/Linden/UDP/PacketPool.cs | 43 ++++++++++++++++++----
1 file changed, 35 insertions(+), 8 deletions(-)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
index fc9406b..3d9f94f 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
@@ -31,6 +31,7 @@ using System.Reflection;
using OpenMetaverse;
using OpenMetaverse.Packets;
using log4net;
+using OpenSim.Framework.Monitoring;
namespace OpenSim.Region.ClientStack.LindenUDP
{
@@ -43,17 +44,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private bool packetPoolEnabled = true;
private bool dataBlockPoolEnabled = true;
+ private PercentageStat m_packetsReusedStat = new PercentageStat(
+ "PacketsReused",
+ "Packets reused",
+ "simulator",
+ "simulator",
+ StatVerbosity.Debug,
+ "Number of packets reused out of all requests to the packet pool");
+
+ private PercentageStat m_blocksReusedStat = new PercentageStat(
+ "BlocksReused",
+ "Blocks reused",
+ "simulator",
+ "simulator",
+ StatVerbosity.Debug,
+ "Number of data blocks reused out of all requests to the packet pool");
+
///
/// Pool of packets available for reuse.
///
private readonly Dictionary> pool = new Dictionary>();
- private static Dictionary> DataBlocks =
- new Dictionary>();
-
- static PacketPool()
- {
- }
+ private static Dictionary> DataBlocks = new Dictionary>();
public static PacketPool Instance
{
@@ -72,8 +84,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP
get { return dataBlockPoolEnabled; }
}
+ private PacketPool()
+ {
+ StatsManager.RegisterStat(m_packetsReusedStat);
+ StatsManager.RegisterStat(m_blocksReusedStat);
+ }
+
public Packet GetPacket(PacketType type)
{
+ m_packetsReusedStat.Consequent++;
+
Packet packet;
if (!packetPoolEnabled)
@@ -89,6 +109,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
else
{
// Recycle old packages
+ m_packetsReusedStat.Antecedent++;
+
packet = (pool[type]).Pop();
}
}
@@ -211,16 +233,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
}
- public static T GetDataBlock() where T: new()
+ public T GetDataBlock() where T: new()
{
lock (DataBlocks)
{
+ m_blocksReusedStat.Consequent++;
+
Stack s;
if (DataBlocks.TryGetValue(typeof(T), out s))
{
if (s.Count > 0)
+ {
+ m_blocksReusedStat.Antecedent++;
return (T)s.Pop();
+ }
}
else
{
@@ -231,7 +258,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
}
- public static void ReturnDataBlock(T block) where T: new()
+ public void ReturnDataBlock(T block) where T: new()
{
if (block == null)
return;
--
cgit v1.1
From 2e9ef015f7b73a3942011a36a9f94ce59d848dc0 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 11 Oct 2012 23:58:37 +0100
Subject: Fix packetpool for ImprovedTerseObjectUpdate packets.
These were neither being returned or in many places reused.
Getting packets from a pool rather than deallocating and reallocating reduces memory churn which in turn reduces garbage collection time and frequency.
---
OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 14 +++++++++++---
OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 2 ++
OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs | 4 ++--
3 files changed, 15 insertions(+), 5 deletions(-)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 62f51d9..dc88686 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -3922,7 +3922,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
List blocks = terseAgentUpdateBlocks.Value;
- ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
+ ImprovedTerseObjectUpdatePacket packet
+ = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
+
packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
packet.RegionData.TimeDilation = timeDilation;
packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
@@ -3967,7 +3969,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
List blocks = terseUpdateBlocks.Value;
- ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
+ ImprovedTerseObjectUpdatePacket packet
+ = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
+ PacketType.ImprovedTerseObjectUpdate);
+
packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
packet.RegionData.TimeDilation = timeDilation;
packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
@@ -12286,7 +12291,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f);
- ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
+ ImprovedTerseObjectUpdatePacket packet
+ = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
+ PacketType.ImprovedTerseObjectUpdate);
+
packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
packet.RegionData.TimeDilation = timeDilation;
packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index ab670a7..6d2cda5 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -420,6 +420,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
byte[] data = packet.ToBytes();
SendPacketData(udpClient, data, packet.Type, category, method);
}
+
+ PacketPool.Instance.ReturnPacket(packet);
}
///
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
index 3d9f94f..fd6b0ed 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
@@ -47,7 +47,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private PercentageStat m_packetsReusedStat = new PercentageStat(
"PacketsReused",
"Packets reused",
- "simulator",
+ "clientstack",
"simulator",
StatVerbosity.Debug,
"Number of packets reused out of all requests to the packet pool");
@@ -55,7 +55,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private PercentageStat m_blocksReusedStat = new PercentageStat(
"BlocksReused",
"Blocks reused",
- "simulator",
+ "clientstack",
"simulator",
StatVerbosity.Debug,
"Number of data blocks reused out of all requests to the packet pool");
--
cgit v1.1
From 8a402850ddbdd9497998774b646c8e0ae6ef1eb8 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 12 Oct 2012 00:21:45 +0100
Subject: Enable reuse of data blocks for ImprovedTerseObjectUpdate using
existing Packetpool code.
---
OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index dc88686..5f9face 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -4964,7 +4964,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Y, -64.0f, 64.0f), data, pos); pos += 2;
Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Z, -64.0f, 64.0f), data, pos); pos += 2;
- ImprovedTerseObjectUpdatePacket.ObjectDataBlock block = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock();
+ ImprovedTerseObjectUpdatePacket.ObjectDataBlock block
+ = PacketPool.Instance.GetDataBlock();
+
block.Data = data;
if (textureEntry != null && textureEntry.Length > 0)
--
cgit v1.1
From 59a17ad676326d5affc2e221ef9c02166a85c6fd Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 12 Oct 2012 00:26:15 +0100
Subject: Fix percentage stats to multiply by 100. Adjust container name for
packetpool stats.
---
OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
index fd6b0ed..a8a1bfe 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
@@ -48,14 +48,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
"PacketsReused",
"Packets reused",
"clientstack",
- "simulator",
+ "packetpool",
StatVerbosity.Debug,
"Number of packets reused out of all requests to the packet pool");
private PercentageStat m_blocksReusedStat = new PercentageStat(
"BlocksReused",
"Blocks reused",
- "clientstack",
+ "packetpool",
"simulator",
StatVerbosity.Debug,
"Number of data blocks reused out of all requests to the packet pool");
--
cgit v1.1
From 21d0cbf7038cfb1b1010310a0f4b455cf9ab700d Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 12 Oct 2012 01:39:37 +0100
Subject: Add AgentUpdate to PacketPool. This is the most common inbound
packet from viewers.
---
.../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 21 +++++++++++++++++++--
OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs | 8 +++++++-
.../Linden/UDP/Tests/BasicCircuitTests.cs | 4 ++--
3 files changed, 28 insertions(+), 5 deletions(-)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 6d2cda5..e3f4679 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -100,9 +100,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// The measured resolution of Environment.TickCount
public readonly float TickCountResolution;
+
/// Number of prim updates to put on the queue each time the
/// OnQueueEmpty event is triggered for updates
public readonly int PrimUpdatesPerCallback;
+
/// Number of texture packets to put on the queue each time the
/// OnQueueEmpty event is triggered for textures
public readonly int TextureSendLimit;
@@ -111,6 +113,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
//PacketEventDictionary packetEvents = new PacketEventDictionary();
/// Incoming packets that are awaiting handling
private OpenMetaverse.BlockingQueue packetInbox = new OpenMetaverse.BlockingQueue();
+
///
//private UDPClientCollection m_clients = new UDPClientCollection();
/// Bandwidth throttle for this UDP server
@@ -121,28 +124,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// Manages authentication for agent circuits
private AgentCircuitManager m_circuitManager;
+
/// Reference to the scene this UDP server is attached to
protected Scene m_scene;
+
/// The X/Y coordinates of the scene this UDP server is attached to
private Location m_location;
+
/// The size of the receive buffer for the UDP socket. This value
/// is passed up to the operating system and used in the system networking
/// stack. Use zero to leave this value as the default
private int m_recvBufferSize;
+
/// Flag to process packets asynchronously or synchronously
private bool m_asyncPacketHandling;
+
/// Tracks whether or not a packet was sent each round so we know
/// whether or not to sleep
private bool m_packetSent;
/// Environment.TickCount of the last time that packet stats were reported to the scene
private int m_elapsedMSSinceLastStatReport = 0;
+
/// Environment.TickCount of the last time the outgoing packet handler executed
private int m_tickLastOutgoingPacketHandler;
+
/// Keeps track of the number of elapsed milliseconds since the last time the outgoing packet handler looped
private int m_elapsedMSOutgoingPacketHandler;
+
/// Keeps track of the number of 100 millisecond periods elapsed in the outgoing packet handler executed
private int m_elapsed100MSOutgoingPacketHandler;
+
/// Keeps track of the number of 500 millisecond periods elapsed in the outgoing packet handler executed
private int m_elapsed500MSOutgoingPacketHandler;
@@ -739,7 +751,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
try
{
- packet = Packet.BuildPacket(buffer.Data, ref packetEnd,
+// packet = Packet.BuildPacket(buffer.Data, ref packetEnd,
+// // Only allocate a buffer for zerodecoding if the packet is zerocoded
+// ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null);
+ packet = PacketPool.Instance.GetPacket(buffer.Data, ref packetEnd,
// Only allocate a buffer for zerodecoding if the packet is zerocoded
((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null);
}
@@ -754,11 +769,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return; // Drop short packet
}
- catch(Exception e)
+ catch (Exception e)
{
if (m_malformedCount < 100)
m_log.DebugFormat("[LLUDPSERVER]: Dropped malformed packet: " + e.ToString());
+
m_malformedCount++;
+
if ((m_malformedCount % 100000) == 0)
m_log.DebugFormat("[LLUDPSERVER]: Received {0} malformed packets so far, probable network attack.", m_malformedCount);
}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
index a8a1bfe..052d334 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
@@ -90,6 +90,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
StatsManager.RegisterStat(m_blocksReusedStat);
}
+ ///
+ /// Gets a packet of the given type.
+ ///
+ ///
+ /// Guaranteed to always return a packet, whether from the pool or newly constructed.
public Packet GetPacket(PacketType type)
{
m_packetsReusedStat.Consequent++;
@@ -160,7 +165,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
PacketType type = GetType(bytes);
- Array.Clear(zeroBuffer, 0, zeroBuffer.Length);
+// Array.Clear(zeroBuffer, 0, zeroBuffer.Length);
int i = 0;
Packet packet = GetPacket(type);
@@ -207,6 +212,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
switch (packet.Type)
{
// List pooling packets here
+ case PacketType.AgentUpdate:
case PacketType.PacketAck:
case PacketType.ObjectUpdate:
case PacketType.ImprovedTerseObjectUpdate:
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs
index 109a8e1..fa9378c 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs
@@ -43,7 +43,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
/// This will contain basic tests for the LindenUDP client stack
///
[TestFixture]
- public class BasicCircuitTests
+ public class BasicCircuitTests : OpenSimTestCase
{
private Scene m_scene;
private TestLLUDPServer m_udpServer;
@@ -143,7 +143,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
public void TestAddClient()
{
TestHelpers.InMethod();
-// XmlConfigurator.Configure();
+// TestHelpers.EnableLogging();
AddUdpServer();
--
cgit v1.1
From 8873a4a8fcaa3372713463094f2cfebeaaf45834 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 12 Oct 2012 01:59:47 +0100
Subject: minor: Fix bug in categorization of blocks reused stat from
packetpool
---
OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
index 052d334..71f6fe1 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
@@ -55,8 +55,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private PercentageStat m_blocksReusedStat = new PercentageStat(
"BlocksReused",
"Blocks reused",
+ "clientstack",
"packetpool",
- "simulator",
StatVerbosity.Debug,
"Number of data blocks reused out of all requests to the packet pool");
--
cgit v1.1
From b7e75d467c2edf052b0cf5216043937ebf583ef4 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Fri, 12 Oct 2012 02:10:30 +0100
Subject: minor: Use && instead of & when deciding whether to print
Improve/ObjectUpdate packet out messages when debug is turned on.
Practical effect is probably none.
---
OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 5f9face..2db8df2 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -11765,7 +11765,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
logPacket = false;
if (DebugPacketLevel <= 50
- & (packet.Type == PacketType.ImprovedTerseObjectUpdate || packet.Type == PacketType.ObjectUpdate))
+ && (packet.Type == PacketType.ImprovedTerseObjectUpdate || packet.Type == PacketType.ObjectUpdate))
logPacket = false;
if (DebugPacketLevel <= 25 && packet.Type == PacketType.ObjectPropertiesFamily)
--
cgit v1.1
From dc460579fd94b2017e334e71ffd20d94a3dec425 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Sat, 13 Oct 2012 01:47:10 +0100
Subject: minor: Fix and elaborate on log information printed when an
unrecognized estate method is received from the client.
---
OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 2db8df2..0d4f09d 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -9063,7 +9063,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
#endregion
- switch (Utils.BytesToString(messagePacket.MethodData.Method))
+ string method = Utils.BytesToString(messagePacket.MethodData.Method);
+
+ switch (method)
{
case "getinfo":
if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false))
@@ -9379,7 +9381,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return true;
default:
- m_log.Error("EstateOwnerMessage: Unknown method requested\n" + messagePacket);
+ m_log.WarnFormat(
+ "[LLCLIENTVIEW]: EstateOwnerMessage: Unknown method {0} requested for {1} in {2}",
+ method, Name, Scene.Name);
+
+ for (int i = 0; i < messagePacket.ParamList.Length; i++)
+ {
+ EstateOwnerMessagePacket.ParamListBlock block = messagePacket.ParamList[i];
+ string data = (string)Utils.BytesToString(block.Parameter);
+ m_log.DebugFormat("[LLCLIENTVIEW]: Param {0}={1}", i, data);
+ }
+
return true;
}
--
cgit v1.1
From 8c2564c05cbf277bef85bba62313f5d5493a4a81 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 16 Oct 2012 00:40:28 +0100
Subject: minor: Comment out the region console caps message for now.
---
OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs
index 36af55f..17c7270 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs
@@ -107,7 +107,7 @@ namespace OpenSim.Region.ClientStack.Linden
UUID capID = UUID.Random();
- m_log.DebugFormat("[REGION CONSOLE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
+// m_log.DebugFormat("[REGION CONSOLE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
caps.RegisterHandler(
"SimConsoleAsync",
new ConsoleHandler("/CAPS/" + capID + "/", "SimConsoleAsync", agentID, this, m_scene));
--
cgit v1.1
From 3ac6a423f7748bf9d5da0d1bd8fc62652ed8e151 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 16 Oct 2012 00:54:25 +0100
Subject: minor: comment out "Registered seed capability" message for "Received
SEED caps request" message for now.
I think this is more useful right now since it tells us if the viewer requested a seed caps at all in various scenarios (such as when teleporting to a new region).
---
.../Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
index 185f9ce..cc69645 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
@@ -163,8 +163,8 @@ namespace OpenSim.Region.ClientStack.Linden
m_HostCapsObj.RegisterHandler(
"SEED", new RestStreamHandler("POST", capsBase + m_requestPath, SeedCapRequest, "SEED", null));
- m_log.DebugFormat(
- "[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_HostCapsObj.AgentID);
+// m_log.DebugFormat(
+// "[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_HostCapsObj.AgentID);
//m_capsHandlers["MapLayer"] =
// new LLSDStreamhandler("POST",
@@ -254,11 +254,12 @@ namespace OpenSim.Region.ClientStack.Linden
public string SeedCapRequest(string request, string path, string param,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{
-// m_log.Debug("[CAPS]: Seed Caps Request in region: " + m_regionName);
+ m_log.DebugFormat(
+ "[CAPS]: Received SEED caps request in {0} for agent {1}", m_regionName, m_HostCapsObj.AgentID);
if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint))
{
- m_log.DebugFormat(
+ m_log.WarnFormat(
"[CAPS]: Unauthorized CAPS client {0} from {1}",
m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint);
--
cgit v1.1
From 0eb457442d87315810fd8280458ca8c0c3e97d23 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 16 Oct 2012 01:31:38 +0100
Subject: minor: Add missing newlines and spacing to help for "debug eq"
console command
---
.../ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
index 0dd0904..47cb049 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
@@ -111,10 +111,10 @@ namespace OpenSim.Region.ClientStack.Linden
false,
"debug eq",
"debug eq [0|1|2]",
- "Turn on event queue debugging"
- + "<= 0 - turns off all event queue logging"
- + ">= 1 - turns on outgoing event logging"
- + ">= 2 - turns on poll notification",
+ "Turn on event queue debugging\n"
+ + " <= 0 - turns off all event queue logging\n"
+ + " >= 1 - turns on outgoing event logging\n"
+ + " >= 2 - turns on poll notification",
HandleDebugEq);
}
else
--
cgit v1.1
From db4ca57590db44aba7d19530285091c7ea4c082c Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 16 Oct 2012 21:55:00 +0100
Subject: Make it possible to separate start and stop lludp packet processing
from the console for debug processes.
This is controlled via the "debug lludp start " and "debug lludp stop " region console commands.
The command "debug lludp status" will show current status.
---
.../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 116 ++++++++++++++++++---
.../ClientStack/Linden/UDP/OpenSimUDPBase.cs | 44 +++++---
2 files changed, 129 insertions(+), 31 deletions(-)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index e3f4679..fc6dd4d 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -37,6 +37,7 @@ using log4net;
using Nini.Config;
using OpenMetaverse.Packets;
using OpenSim.Framework;
+using OpenSim.Framework.Console;
using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Scenes;
using OpenMetaverse;
@@ -274,16 +275,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public void Start()
{
- if (m_scene == null)
- throw new InvalidOperationException("[LLUDPSERVER]: Cannot LLUDPServer.Start() without an IScene reference");
+ StartInbound();
+ StartOutbound();
+ m_elapsedMSSinceLastStatReport = Environment.TickCount;
+ }
+
+ private void StartInbound()
+ {
m_log.InfoFormat(
- "[LLUDPSERVER]: Starting the LLUDP server in {0} mode",
+ "[LLUDPSERVER]: Starting inbound packet processing for the LLUDP server in {0} mode",
m_asyncPacketHandling ? "asynchronous" : "synchronous");
- base.Start(m_recvBufferSize, m_asyncPacketHandling);
+ base.StartInbound(m_recvBufferSize, m_asyncPacketHandling);
- // Start the packet processing threads
+ // This thread will process the packets received that are placed on the packetInbox
Watchdog.StartThread(
IncomingPacketHandler,
string.Format("Incoming Packets ({0})", m_scene.RegionInfo.RegionName),
@@ -292,7 +298,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
true,
GetWatchdogIncomingAlarmData,
Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS);
+ }
+ private void StartOutbound()
+ {
+ m_log.Info("[LLUDPSERVER]: Starting outbound packet processing for the LLUDP server");
+
+ base.StartOutbound();
+
+ // This thread will process the packets received that are placed on the packetInbox
Watchdog.StartThread(
OutgoingPacketHandler,
string.Format("Outgoing Packets ({0})", m_scene.RegionInfo.RegionName),
@@ -301,8 +315,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
true,
GetWatchdogOutgoingAlarmData,
Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS);
+ }
- m_elapsedMSSinceLastStatReport = Environment.TickCount;
+ public new void Stop()
+ {
+ m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName);
+ base.StopOutbound();
+ base.StopInbound();
}
///
@@ -327,12 +346,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
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);
- base.Stop();
- }
-
public void AddScene(IScene scene)
{
if (m_scene != null)
@@ -349,6 +362,81 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_scene = (Scene)scene;
m_location = new Location(m_scene.RegionInfo.RegionHandle);
+
+ MainConsole.Instance.Commands.AddCommand(
+ "Debug",
+ false,
+ "debug lludp start",
+ "debug lludp start ",
+ "Control LLUDP packet processing.",
+ "No effect if packet processing has already started.\n"
+ + "in - start inbound processing.\n"
+ + "out - start outbound processing.\n"
+ + "all - start in and outbound processing.\n",
+ HandleStartCommand);
+
+ MainConsole.Instance.Commands.AddCommand(
+ "Debug",
+ false,
+ "debug lludp stop",
+ "debug lludp stop ",
+ "Stop LLUDP packet processing.",
+ "No effect if packet processing has already stopped.\n"
+ + "in - stop inbound processing.\n"
+ + "out - stop outbound processing.\n"
+ + "all - stop in and outbound processing.\n",
+ HandleStopCommand);
+
+ MainConsole.Instance.Commands.AddCommand(
+ "Debug",
+ false,
+ "debug lludp status",
+ "debug lludp status",
+ "Return status of LLUDP packet processing.",
+ HandleStatusCommand);
+ }
+
+ private void HandleStartCommand(string module, string[] args)
+ {
+ if (args.Length != 4)
+ {
+ MainConsole.Instance.Output("Usage: debug lludp start ");
+ return;
+ }
+
+ string subCommand = args[3];
+
+ if (subCommand == "in" || subCommand == "all")
+ StartInbound();
+
+ if (subCommand == "out" || subCommand == "all")
+ StartOutbound();
+ }
+
+ private void HandleStopCommand(string module, string[] args)
+ {
+ if (args.Length != 4)
+ {
+ MainConsole.Instance.Output("Usage: debug lludp stop ");
+ return;
+ }
+
+ string subCommand = args[3];
+
+ if (subCommand == "in" || subCommand == "all")
+ StopInbound();
+
+ if (subCommand == "out" || subCommand == "all")
+ StopOutbound();
+ }
+
+ private void HandleStatusCommand(string module, string[] args)
+ {
+ MainConsole.Instance.OutputFormat(
+ "IN LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningInbound ? "enabled" : "disabled");
+
+ MainConsole.Instance.OutputFormat(
+ "OUT LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningOutbound ? "enabled" : "disabled");
}
public bool HandlesRegion(Location x)
@@ -1174,7 +1262,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// on to en-US to avoid number parsing issues
Culture.SetCurrentCulture();
- while (base.IsRunning)
+ while (base.IsRunningInbound)
{
try
{
@@ -1216,7 +1304,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Action generic every round
Action clientPacketHandler = ClientOutgoingPacketHandler;
- while (base.IsRunning)
+ while (base.IsRunningOutbound)
{
try
{
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index 039379d..828c23c 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
@@ -58,11 +58,12 @@ namespace OpenMetaverse
/// Flag to process packets asynchronously or synchronously
private bool m_asyncPacketHandling;
- /// The all important shutdown flag
- private volatile bool m_shutdownFlag = true;
+ /// Returns true if the server is currently listening for inbound packets, otherwise false
+ public bool IsRunningInbound { get; private set; }
- /// Returns true if the server is currently listening, otherwise false
- public bool IsRunning { get { return !m_shutdownFlag; } }
+ /// Returns true if the server is currently sending outbound packets, otherwise false
+ /// If IsRunningOut = false, then any request to send a packet is simply dropped.
+ public bool IsRunningOutbound { get; private set; }
///
/// Default constructor
@@ -76,7 +77,7 @@ namespace OpenMetaverse
}
///
- /// Start the UDP server
+ /// Start inbound UDP packet handling.
///
/// The size of the receive buffer for
/// the UDP socket. This value is passed up to the operating system
@@ -91,11 +92,11 @@ namespace OpenMetaverse
/// manner (not throwing an exception when the remote side resets the
/// connection). This call is ignored on Mono where the flag is not
/// necessary
- public void Start(int recvBufferSize, bool asyncPacketHandling)
+ public void StartInbound(int recvBufferSize, bool asyncPacketHandling)
{
m_asyncPacketHandling = asyncPacketHandling;
- if (m_shutdownFlag)
+ if (!IsRunningInbound)
{
const int SIO_UDP_CONNRESET = -1744830452;
@@ -127,8 +128,7 @@ namespace OpenMetaverse
m_udpSocket.Bind(ipep);
- // we're not shutting down, we're starting up
- m_shutdownFlag = false;
+ IsRunningInbound = true;
// kick off an async receive. The Start() method will return, the
// actual receives will occur asynchronously and will be caught in
@@ -138,28 +138,38 @@ namespace OpenMetaverse
}
///
- /// Stops the UDP server
+ /// Start outbound UDP packet handling.
///
- public void Stop()
+ public void StartOutbound()
{
- if (!m_shutdownFlag)
+ IsRunningOutbound = true;
+ }
+
+ public void StopInbound()
+ {
+ if (IsRunningInbound)
{
// wait indefinitely for a writer lock. Once this is called, the .NET runtime
// will deny any more reader locks, in effect blocking all other send/receive
- // threads. Once we have the lock, we set shutdownFlag to inform the other
+ // threads. Once we have the lock, we set IsRunningInbound = false to inform the other
// threads that the socket is closed.
- m_shutdownFlag = true;
+ IsRunningInbound = false;
m_udpSocket.Close();
}
}
+ public void StopOutbound()
+ {
+ IsRunningOutbound = false;
+ }
+
private void AsyncBeginReceive()
{
// allocate a packet buffer
//WrappedObject wrappedBuffer = Pool.CheckOut();
UDPPacketBuffer buf = new UDPPacketBuffer();
- if (!m_shutdownFlag)
+ if (IsRunningInbound)
{
try
{
@@ -212,7 +222,7 @@ namespace OpenMetaverse
{
// Asynchronous receive operations will complete here through the call
// to AsyncBeginReceive
- if (!m_shutdownFlag)
+ if (IsRunningInbound)
{
// Asynchronous mode will start another receive before the
// callback for this packet is even fired. Very parallel :-)
@@ -252,7 +262,7 @@ namespace OpenMetaverse
public void AsyncBeginSend(UDPPacketBuffer buf)
{
- if (!m_shutdownFlag)
+ if (IsRunningOutbound)
{
try
{
--
cgit v1.1
From fc861c7904840b2b0b9de0621e9b5d976c8071b1 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 16 Oct 2012 23:35:05 +0100
Subject: Add optional pool for the UDPPacketBuffer objects that handle all
incoming UDP data.
Even when an avatar is standing still, it's sending in a constant stream of AgentUpdate packets that the client creates new UDPPacketBuffer objects to handle.
This option pools those objects. This reduces memory churn.
Currently off by default. Works but the scope can be expanded.
---
.../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 42 ++++++++++++----------
.../ClientStack/Linden/UDP/OpenSimUDPBase.cs | 31 ++++++++++++----
2 files changed, 49 insertions(+), 24 deletions(-)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index fc6dd4d..42247ca 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -188,7 +188,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
///
private IClientAPI m_currentIncomingClient;
- public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager)
+ public LLUDPServer(
+ IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port,
+ IConfigSource configSource, AgentCircuitManager circuitManager)
: base(listenIP, (int)port)
{
#region Environment.TickCount Measurement
@@ -242,6 +244,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
PacketPool.Instance.RecyclePackets = packetConfig.GetBoolean("RecyclePackets", true);
PacketPool.Instance.RecycleDataBlocks = packetConfig.GetBoolean("RecycleDataBlocks", true);
+ UsePools = packetConfig.GetBoolean("RecycleBaseUDPPackets", false);
}
#region BinaryStats
@@ -284,8 +287,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private void StartInbound()
{
m_log.InfoFormat(
- "[LLUDPSERVER]: Starting inbound packet processing for the LLUDP server in {0} mode",
- m_asyncPacketHandling ? "asynchronous" : "synchronous");
+ "[LLUDPSERVER]: Starting inbound packet processing for the LLUDP server in {0} mode with UsePools = {1}",
+ m_asyncPacketHandling ? "asynchronous" : "synchronous", UsePools);
base.StartInbound(m_recvBufferSize, m_asyncPacketHandling);
@@ -300,7 +303,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS);
}
- private void StartOutbound()
+ private new void StartOutbound()
{
m_log.Info("[LLUDPSERVER]: Starting outbound packet processing for the LLUDP server");
@@ -317,7 +320,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS);
}
- public new void Stop()
+ public void Stop()
{
m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName);
base.StopOutbound();
@@ -806,7 +809,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
LLUDPClient udpClient = null;
Packet packet = null;
int packetEnd = buffer.DataLength - 1;
- IPEndPoint address = (IPEndPoint)buffer.RemoteEndPoint;
+ IPEndPoint endPoint = (IPEndPoint)buffer.RemoteEndPoint;
#region Decoding
@@ -816,7 +819,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// "[LLUDPSERVER]: Dropping undersized packet with {0} bytes received from {1} in {2}",
// buffer.DataLength, buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
- return; // Drop undersizd packet
+ return; // Drop undersized packet
}
int headerLen = 7;
@@ -842,6 +845,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// packet = Packet.BuildPacket(buffer.Data, ref packetEnd,
// // Only allocate a buffer for zerodecoding if the packet is zerocoded
// ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null);
+ // If OpenSimUDPBase.UsePool == true (which is currently separate from the PacketPool) then we
+ // assume that packet construction does not retain a reference to byte[] buffer.Data (instead, all
+ // bytes are copied out).
packet = PacketPool.Instance.GetPacket(buffer.Data, ref packetEnd,
// Only allocate a buffer for zerodecoding if the packet is zerocoded
((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null);
@@ -884,7 +890,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// UseCircuitCode handling
if (packet.Type == PacketType.UseCircuitCode)
{
- object[] array = new object[] { buffer, packet };
+ // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
+ // buffer.
+ object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
Util.FireAndForget(HandleUseCircuitCode, array);
@@ -893,7 +901,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Determine which agent this packet came from
IClientAPI client;
- if (!m_scene.TryGetClient(address, out client) || !(client is LLClientView))
+ if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
{
//m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName);
return;
@@ -1091,21 +1099,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private void HandleUseCircuitCode(object o)
{
- IPEndPoint remoteEndPoint = null;
+ IPEndPoint endPoint = null;
IClientAPI client = null;
try
{
// DateTime startTime = DateTime.Now;
object[] array = (object[])o;
- UDPPacketBuffer buffer = (UDPPacketBuffer)array[0];
+ endPoint = (IPEndPoint)array[0];
UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1];
m_log.DebugFormat(
"[LLUDPSERVER]: Handling UseCircuitCode request for circuit {0} to {1} from IP {2}",
- uccp.CircuitCode.Code, m_scene.RegionInfo.RegionName, buffer.RemoteEndPoint);
-
- remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;
+ uccp.CircuitCode.Code, m_scene.RegionInfo.RegionName, endPoint);
AuthenticateResponse sessionInfo;
if (IsClientAuthorized(uccp, out sessionInfo))
@@ -1116,13 +1122,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
uccp.CircuitCode.Code,
uccp.CircuitCode.ID,
uccp.CircuitCode.SessionID,
- remoteEndPoint,
+ endPoint,
sessionInfo);
// Send ack straight away to let the viewer know that the connection is active.
// The client will be null if it already exists (e.g. if on a region crossing the client sends a use
// circuit code to the existing child agent. This is not particularly obvious.
- SendAckImmediate(remoteEndPoint, uccp.Header.Sequence);
+ SendAckImmediate(endPoint, uccp.Header.Sequence);
// We only want to send initial data to new clients, not ones which are being converted from child to root.
if (client != null)
@@ -1133,7 +1139,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Don't create clients for unauthorized requesters.
m_log.WarnFormat(
"[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}",
- uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, remoteEndPoint);
+ uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint);
}
// m_log.DebugFormat(
@@ -1145,7 +1151,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
m_log.ErrorFormat(
"[LLUDPSERVER]: UseCircuitCode handling from endpoint {0}, client {1} {2} failed. Exception {3}{4}",
- remoteEndPoint != null ? remoteEndPoint.ToString() : "n/a",
+ endPoint != null ? endPoint.ToString() : "n/a",
client != null ? client.Name : "unknown",
client != null ? client.AgentId.ToString() : "unknown",
e.Message,
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index 828c23c..6e6b3ef 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
@@ -30,6 +30,7 @@ using System.Net;
using System.Net.Sockets;
using System.Threading;
using log4net;
+using OpenSim.Framework;
namespace OpenMetaverse
{
@@ -58,6 +59,16 @@ namespace OpenMetaverse
/// Flag to process packets asynchronously or synchronously
private bool m_asyncPacketHandling;
+ ///
+ /// Pool to use for handling data. May be null if UsePools = false;
+ ///
+ protected OpenSim.Framework.Pool m_pool;
+
+ ///
+ /// Are we to use object pool(s) to reduce memory churn when receiving data?
+ ///
+ public bool UsePools { get; protected set; }
+
/// Returns true if the server is currently listening for inbound packets, otherwise false
public bool IsRunningInbound { get; private set; }
@@ -70,6 +81,7 @@ namespace OpenMetaverse
///
/// Local IP address to bind the server to
/// Port to listening for incoming UDP packets on
+ /// /// Are we to use an object pool to get objects for handing inbound data?
public OpenSimUDPBase(IPAddress bindAddress, int port)
{
m_localBindAddress = bindAddress;
@@ -94,6 +106,11 @@ namespace OpenMetaverse
/// necessary
public void StartInbound(int recvBufferSize, bool asyncPacketHandling)
{
+ if (UsePools)
+ m_pool = new Pool(() => new UDPPacketBuffer(), 500);
+ else
+ m_pool = null;
+
m_asyncPacketHandling = asyncPacketHandling;
if (!IsRunningInbound)
@@ -165,9 +182,12 @@ namespace OpenMetaverse
private void AsyncBeginReceive()
{
- // allocate a packet buffer
- //WrappedObject wrappedBuffer = Pool.CheckOut();
- UDPPacketBuffer buf = new UDPPacketBuffer();
+ UDPPacketBuffer buf;
+
+ if (UsePools)
+ buf = m_pool.GetObject();
+ else
+ buf = new UDPPacketBuffer();
if (IsRunningInbound)
{
@@ -231,8 +251,6 @@ namespace OpenMetaverse
// get the buffer that was created in AsyncBeginReceive
// this is the received data
- //WrappedObject wrappedBuffer = (WrappedObject)iar.AsyncState;
- //UDPPacketBuffer buffer = wrappedBuffer.Instance;
UDPPacketBuffer buffer = (UDPPacketBuffer)iar.AsyncState;
try
@@ -249,7 +267,8 @@ namespace OpenMetaverse
catch (ObjectDisposedException) { }
finally
{
- //wrappedBuffer.Dispose();
+ if (UsePools)
+ m_pool.ReturnObject(buffer);
// Synchronous mode waits until the packet callback completes
// before starting the receive to fetch another packet
--
cgit v1.1
From f35826eb31e2f286e3ae5bdbcf8c3beb4723d5d9 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 16 Oct 2012 23:50:45 +0100
Subject: minor: Make BasicCircuitTests.SetUp() call overriden base method
instead of ignoring it.
---
OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs
index fa9378c..556df30 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs
@@ -65,8 +65,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
}
[SetUp]
- public void SetUp()
+ public override void SetUp()
{
+ base.SetUp();
m_scene = new SceneHelpers().SetupScene();
}
--
cgit v1.1
From 2ed59ad8ac3ec836517b60580f13ab37102a0c67 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 17 Oct 2012 21:08:15 +0100
Subject: If RecycleBaseUDPPackets = true, also pool IncomingPackets to reduce
memory churn
---
.../ClientStack/Linden/UDP/IncomingPacket.cs | 7 +++++-
.../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 25 +++++++++++++++++++++-
2 files changed, 30 insertions(+), 2 deletions(-)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs b/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs
index 1b8535c..e22670b 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs
@@ -45,7 +45,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public Packet Packet;
///
- /// Default constructor
+ /// No arg constructor.
+ ///
+ public IncomingPacket() {}
+
+ ///
+ /// Constructor
///
/// Reference to the client this packet came from
/// Packet data
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 42247ca..286d931 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -168,6 +168,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// Flag to signal when clients should send pings
protected bool m_sendPing;
+ private Pool m_incomingPacketPool;
+
private int m_defaultRTO = 0;
private int m_maxRTO = 0;
private int m_ackTimeout = 0;
@@ -274,6 +276,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_throttle = new TokenBucket(null, sceneThrottleBps);
ThrottleRates = new ThrottleRates(configSource);
+
+ if (UsePools)
+ m_incomingPacketPool = new Pool(() => new IncomingPacket(), 500);
}
public void Start()
@@ -1012,8 +1017,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#endregion Ping Check Handling
+ IncomingPacket incomingPacket;
+
// Inbox insertion
- packetInbox.Enqueue(new IncomingPacket((LLClientView)client, packet));
+ if (UsePools)
+ {
+ incomingPacket = m_incomingPacketPool.GetObject();
+ incomingPacket.Client = (LLClientView)client;
+ incomingPacket.Packet = packet;
+ }
+ else
+ {
+ incomingPacket = new IncomingPacket((LLClientView)client, packet);
+ }
+
+ packetInbox.Enqueue(incomingPacket);
}
#region BinaryStats
@@ -1283,7 +1301,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
if (packetInbox.Dequeue(100, ref incomingPacket))
+ {
ProcessInPacket(incomingPacket);//, incomingPacket); Util.FireAndForget(ProcessInPacket, incomingPacket);
+
+ if (UsePools)
+ m_incomingPacketPool.ReturnObject(incomingPacket);
+ }
}
catch (Exception ex)
{
--
cgit v1.1
From faf6b568393d8edfed103e0a656c98322c195e95 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 17 Oct 2012 23:08:14 +0100
Subject: Explicitly return only the incoming AgentUpdate packet as this is the
only one we pool atm, rather than attempting to return all incoming packets.
---
OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 11 +++++++----
OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 17 +++++++++++++++--
OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs | 10 ++++++++--
3 files changed, 30 insertions(+), 8 deletions(-)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 0d4f09d..1e93b84 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -5425,16 +5425,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#region Scene/Avatar
- private bool HandleAgentUpdate(IClientAPI sener, Packet Pack)
+ private bool HandleAgentUpdate(IClientAPI sener, Packet packet)
{
if (OnAgentUpdate != null)
{
bool update = false;
- AgentUpdatePacket agenUpdate = (AgentUpdatePacket)Pack;
+ AgentUpdatePacket agenUpdate = (AgentUpdatePacket)packet;
#region Packet Session and User Check
if (agenUpdate.AgentData.SessionID != SessionId || agenUpdate.AgentData.AgentID != AgentId)
+ {
+ PacketPool.Instance.ReturnPacket(packet);
return false;
+ }
#endregion
AgentUpdatePacket.AgentDataBlock x = agenUpdate.AgentData;
@@ -5499,6 +5502,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
}
+ PacketPool.Instance.ReturnPacket(packet);
+
return true;
}
@@ -11851,8 +11856,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (!ProcessPacketMethod(packet))
m_log.Warn("[CLIENT]: unhandled packet " + packet.Type);
-
- PacketPool.Instance.ReturnPacket(packet);
}
private static PrimitiveBaseShape GetShapeFromAddPacket(ObjectAddPacket addPacket)
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 286d931..419de66 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -314,7 +314,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
base.StartOutbound();
- // This thread will process the packets received that are placed on the packetInbox
Watchdog.StartThread(
OutgoingPacketHandler,
string.Format("Outgoing Packets ({0})", m_scene.RegionInfo.RegionName),
@@ -930,6 +929,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Handle appended ACKs
if (packet.Header.AppendedAcks && packet.Header.AckList != null)
{
+// m_log.DebugFormat(
+// "[LLUDPSERVER]: Handling {0} appended acks from {1} in {2}",
+// packet.Header.AckList.Length, client.Name, m_scene.Name);
+
for (int i = 0; i < packet.Header.AckList.Length; i++)
udpClient.NeedAcks.Acknowledge(packet.Header.AckList[i], now, packet.Header.Resent);
}
@@ -939,6 +942,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
PacketAckPacket ackPacket = (PacketAckPacket)packet;
+// m_log.DebugFormat(
+// "[LLUDPSERVER]: Handling {0} packet acks for {1} in {2}",
+// ackPacket.Packets.Length, client.Name, m_scene.Name);
+
for (int i = 0; i < ackPacket.Packets.Length; i++)
udpClient.NeedAcks.Acknowledge(ackPacket.Packets[i].ID, now, packet.Header.Resent);
@@ -952,6 +959,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (packet.Header.Reliable)
{
+// m_log.DebugFormat(
+// "[LLUDPSERVER]: Adding ack request for {0} {1} from {2} in {3}",
+// packet.Type, packet.Header.Sequence, client.Name, m_scene.Name);
+
udpClient.PendingAcks.Enqueue(packet.Header.Sequence);
// This is a somewhat odd sequence of steps to pull the client.BytesSinceLastACK value out,
@@ -998,6 +1009,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (packet.Type == PacketType.StartPingCheck)
{
+// m_log.DebugFormat("[LLUDPSERVER]: Handling ping from {0} in {1}", client.Name, m_scene.Name);
+
// We don't need to do anything else with ping checks
StartPingCheckPacket startPing = (StartPingCheckPacket)packet;
CompletePing(udpClient, startPing.PingID.PingID);
@@ -1286,7 +1299,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// on to en-US to avoid number parsing issues
Culture.SetCurrentCulture();
- while (base.IsRunningInbound)
+ while (IsRunningInbound)
{
try
{
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
index 71f6fe1..2a3d14f 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
@@ -108,15 +108,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
if (!pool.ContainsKey(type) || pool[type] == null || (pool[type]).Count == 0)
{
+// m_log.DebugFormat("[PACKETPOOL]: Building {0} packet", type);
+
// Creating a new packet if we cannot reuse an old package
packet = Packet.BuildPacket(type);
}
else
{
+// m_log.DebugFormat("[PACKETPOOL]: Pulling {0} packet", type);
+
// Recycle old packages
m_packetsReusedStat.Antecedent++;
- packet = (pool[type]).Pop();
+ packet = pool[type].Pop();
}
}
@@ -227,7 +231,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if ((pool[type]).Count < 50)
{
- (pool[type]).Push(packet);
+// m_log.DebugFormat("[PACKETPOOL]: Pushing {0} packet", type);
+
+ pool[type].Push(packet);
}
}
break;
--
cgit v1.1
From 3ec2923022dbc3e0b5411b17c6495dab6d641f0b Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 17 Oct 2012 23:54:05 +0100
Subject: Reuse the same AgentUpdateArgs object for each AgentUpdate UDP packet
(of which there are 10 a second) rather than constructing a new one every
time.
We can do this because AgentUpdate packets are handled synchronously.
---
.../Region/ClientStack/Linden/UDP/LLClientView.cs | 109 +++++++++++++--------
1 file changed, 68 insertions(+), 41 deletions(-)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 1e93b84..65daca0 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -92,8 +92,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public event ObjectDeselect OnObjectDetach;
public event ObjectDrop OnObjectDrop;
public event Action OnCompleteMovementToRegion;
+
+ ///
+ /// Called when an AgentUpdate message is received and before OnAgentUpdate.
+ ///
+ ///
+ /// Listeners must not retain a reference to AgentUpdateArgs since this object is reused for subsequent AgentUpdates.
+ ///
public event UpdateAgent OnPreAgentUpdate;
+
+ ///
+ /// Called when an AgentUpdate message is received and after OnPreAgentUpdate.
+ ///
+ ///
+ /// Listeners must not retain a reference to AgentUpdateArgs since this object is reused for subsequent AgentUpdates.
+ ///
public event UpdateAgent OnAgentUpdate;
+
public event AgentRequestSit OnAgentRequestSit;
public event AgentSit OnAgentSit;
public event AvatarPickerRequest OnAvatarPickerRequest;
@@ -347,7 +362,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private int m_moneyBalance;
private int m_animationSequenceNumber = 1;
private bool m_SendLogoutPacketWhenClosing = true;
- private AgentUpdateArgs lastarg;
+
+ ///
+ /// We retain a single AgentUpdateArgs so that we can constantly reuse it rather than construct a new one for
+ /// every single incoming AgentUpdate. Every client sends 10 AgentUpdate UDP messages per second, even if it
+ /// is doing absolutely nothing.
+ ///
+ ///
+ /// This does mean that agent updates must be processed synchronously, at least for each client, and called methods
+ /// cannot retain a reference to it outside of that method.
+ ///
+ private AgentUpdateArgs m_lastAgentUpdateArgs;
protected Dictionary m_packetHandlers = new Dictionary();
protected Dictionary m_genericPacketHandlers = new Dictionary(); //PauPaw:Local Generic Message handlers
@@ -5198,7 +5223,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
protected virtual void RegisterLocalPacketHandlers()
{
AddLocalPacketHandler(PacketType.LogoutRequest, HandleLogout);
+
+ // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs
+ // for each AgentUpdate packet.
AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false);
+
AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false);
AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false);
AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false);
@@ -5429,73 +5458,71 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
if (OnAgentUpdate != null)
{
- bool update = false;
- AgentUpdatePacket agenUpdate = (AgentUpdatePacket)packet;
+ AgentUpdatePacket agentUpdate = (AgentUpdatePacket)packet;
#region Packet Session and User Check
- if (agenUpdate.AgentData.SessionID != SessionId || agenUpdate.AgentData.AgentID != AgentId)
+ if (agentUpdate.AgentData.SessionID != SessionId || agentUpdate.AgentData.AgentID != AgentId)
{
PacketPool.Instance.ReturnPacket(packet);
return false;
}
#endregion
- AgentUpdatePacket.AgentDataBlock x = agenUpdate.AgentData;
-
- // We can only check when we have something to check
- // against.
+ bool update = false;
+ AgentUpdatePacket.AgentDataBlock x = agentUpdate.AgentData;
- if (lastarg != null)
+ if (m_lastAgentUpdateArgs != null)
{
+ // These should be ordered from most-likely to
+ // least likely to change. I've made an initial
+ // guess at that.
update =
(
- (x.BodyRotation != lastarg.BodyRotation) ||
- (x.CameraAtAxis != lastarg.CameraAtAxis) ||
- (x.CameraCenter != lastarg.CameraCenter) ||
- (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
- (x.CameraUpAxis != lastarg.CameraUpAxis) ||
- (x.ControlFlags != lastarg.ControlFlags) ||
- (x.Far != lastarg.Far) ||
- (x.Flags != lastarg.Flags) ||
- (x.State != lastarg.State) ||
- (x.HeadRotation != lastarg.HeadRotation) ||
- (x.SessionID != lastarg.SessionID) ||
- (x.AgentID != lastarg.AgentID)
+ (x.BodyRotation != m_lastAgentUpdateArgs.BodyRotation) ||
+ (x.CameraAtAxis != m_lastAgentUpdateArgs.CameraAtAxis) ||
+ (x.CameraCenter != m_lastAgentUpdateArgs.CameraCenter) ||
+ (x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) ||
+ (x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) ||
+ (x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) ||
+ (x.Far != m_lastAgentUpdateArgs.Far) ||
+ (x.Flags != m_lastAgentUpdateArgs.Flags) ||
+ (x.State != m_lastAgentUpdateArgs.State) ||
+ (x.HeadRotation != m_lastAgentUpdateArgs.HeadRotation) ||
+ (x.SessionID != m_lastAgentUpdateArgs.SessionID) ||
+ (x.AgentID != m_lastAgentUpdateArgs.AgentID)
);
}
else
{
+ m_lastAgentUpdateArgs = new AgentUpdateArgs();
update = true;
}
- // These should be ordered from most-likely to
- // least likely to change. I've made an initial
- // guess at that.
-
if (update)
{
// m_log.DebugFormat("[LLCLIENTVIEW]: Triggered AgentUpdate for {0}", sener.Name);
- AgentUpdateArgs arg = new AgentUpdateArgs();
- arg.AgentID = x.AgentID;
- arg.BodyRotation = x.BodyRotation;
- arg.CameraAtAxis = x.CameraAtAxis;
- arg.CameraCenter = x.CameraCenter;
- arg.CameraLeftAxis = x.CameraLeftAxis;
- arg.CameraUpAxis = x.CameraUpAxis;
- arg.ControlFlags = x.ControlFlags;
- arg.Far = x.Far;
- arg.Flags = x.Flags;
- arg.HeadRotation = x.HeadRotation;
- arg.SessionID = x.SessionID;
- arg.State = x.State;
+ m_lastAgentUpdateArgs.AgentID = x.AgentID;
+ m_lastAgentUpdateArgs.BodyRotation = x.BodyRotation;
+ m_lastAgentUpdateArgs.CameraAtAxis = x.CameraAtAxis;
+ m_lastAgentUpdateArgs.CameraCenter = x.CameraCenter;
+ m_lastAgentUpdateArgs.CameraLeftAxis = x.CameraLeftAxis;
+ m_lastAgentUpdateArgs.CameraUpAxis = x.CameraUpAxis;
+ m_lastAgentUpdateArgs.ControlFlags = x.ControlFlags;
+ m_lastAgentUpdateArgs.Far = x.Far;
+ m_lastAgentUpdateArgs.Flags = x.Flags;
+ m_lastAgentUpdateArgs.HeadRotation = x.HeadRotation;
+ m_lastAgentUpdateArgs.SessionID = x.SessionID;
+ m_lastAgentUpdateArgs.State = x.State;
+
UpdateAgent handlerAgentUpdate = OnAgentUpdate;
UpdateAgent handlerPreAgentUpdate = OnPreAgentUpdate;
- lastarg = arg; // save this set of arguments for nexttime
+
if (handlerPreAgentUpdate != null)
- OnPreAgentUpdate(this, arg);
+ OnPreAgentUpdate(this, m_lastAgentUpdateArgs);
+
if (handlerAgentUpdate != null)
- OnAgentUpdate(this, arg);
+ OnAgentUpdate(this, m_lastAgentUpdateArgs);
handlerAgentUpdate = null;
handlerPreAgentUpdate = null;
--
cgit v1.1
From 0811f3d28d70432e4657df735b5337726eb2f53f Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 18 Oct 2012 00:34:10 +0100
Subject: minor: Remove event method doc from LLClientView that I forgot in the
last commit (1de80c)
---
OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 15 ---------------
1 file changed, 15 deletions(-)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 65daca0..7427c59 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -92,23 +92,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public event ObjectDeselect OnObjectDetach;
public event ObjectDrop OnObjectDrop;
public event Action OnCompleteMovementToRegion;
-
- ///
- /// Called when an AgentUpdate message is received and before OnAgentUpdate.
- ///
- ///
- /// Listeners must not retain a reference to AgentUpdateArgs since this object is reused for subsequent AgentUpdates.
- ///
public event UpdateAgent OnPreAgentUpdate;
-
- ///
- /// Called when an AgentUpdate message is received and after OnPreAgentUpdate.
- ///
- ///
- /// Listeners must not retain a reference to AgentUpdateArgs since this object is reused for subsequent AgentUpdates.
- ///
public event UpdateAgent OnAgentUpdate;
-
public event AgentRequestSit OnAgentRequestSit;
public event AgentSit OnAgentSit;
public event AvatarPickerRequest OnAvatarPickerRequest;
--
cgit v1.1
From 4578ff74fec7500902f58fbdee6ce5a6b39601fb Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 23 Oct 2012 01:50:05 +0100
Subject: Add object count stats for new IncomingPacket and UDPPacketBuffer
pools if they are enabled. Add count stats for existing LLUDP pool.
This introduces a pull stat type in addition to the push stat type.
A pull stat takes a method on construction which knows how to update the stat on request.
In this way, special interfaces for pull stat collection are not necessary.
---
.../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 14 ++++++++
.../ClientStack/Linden/UDP/OpenSimUDPBase.cs | 17 +++++++++
.../Region/ClientStack/Linden/UDP/PacketPool.cs | 40 ++++++++++++++++++----
3 files changed, 65 insertions(+), 6 deletions(-)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index 419de66..bcfd392 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -278,7 +278,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
ThrottleRates = new ThrottleRates(configSource);
if (UsePools)
+ {
m_incomingPacketPool = new Pool(() => new IncomingPacket(), 500);
+
+ StatsManager.RegisterStat(
+ new Stat(
+ "IncomingPacketPoolCount",
+ "Objects within incoming packet pool",
+ "The number of objects currently stored within the incoming packet pool",
+ "",
+ "clientstack",
+ "packetpool",
+ StatType.Pull,
+ stat => stat.Value = m_incomingPacketPool.Count,
+ StatVerbosity.Debug));
+ }
}
public void Start()
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index 6e6b3ef..18abfd6 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
@@ -31,6 +31,7 @@ using System.Net.Sockets;
using System.Threading;
using log4net;
using OpenSim.Framework;
+using OpenSim.Framework.Monitoring;
namespace OpenMetaverse
{
@@ -107,9 +108,25 @@ namespace OpenMetaverse
public void StartInbound(int recvBufferSize, bool asyncPacketHandling)
{
if (UsePools)
+ {
m_pool = new Pool(() => new UDPPacketBuffer(), 500);
+
+ StatsManager.RegisterStat(
+ new Stat(
+ "UDPPacketBufferPoolCount",
+ "Objects within the UDPPacketBuffer pool",
+ "The number of objects currently stored within the UDPPacketBuffer pool",
+ "",
+ "clientstack",
+ "packetpool",
+ StatType.Pull,
+ stat => stat.Value = m_pool.Count,
+ StatVerbosity.Debug));
+ }
else
+ {
m_pool = null;
+ }
m_asyncPacketHandling = asyncPacketHandling;
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
index 2a3d14f..9f22fb4 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
@@ -47,18 +47,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private PercentageStat m_packetsReusedStat = new PercentageStat(
"PacketsReused",
"Packets reused",
+ "Number of packets reused out of all requests to the packet pool",
"clientstack",
"packetpool",
- StatVerbosity.Debug,
- "Number of packets reused out of all requests to the packet pool");
+ StatType.Push,
+ null,
+ StatVerbosity.Debug);
private PercentageStat m_blocksReusedStat = new PercentageStat(
- "BlocksReused",
- "Blocks reused",
+ "PacketDataBlocksReused",
+ "Packet data blocks reused",
+ "Number of data blocks reused out of all requests to the packet pool",
"clientstack",
"packetpool",
- StatVerbosity.Debug,
- "Number of data blocks reused out of all requests to the packet pool");
+ StatType.Push,
+ null,
+ StatVerbosity.Debug);
///
/// Pool of packets available for reuse.
@@ -88,6 +92,30 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
StatsManager.RegisterStat(m_packetsReusedStat);
StatsManager.RegisterStat(m_blocksReusedStat);
+
+ StatsManager.RegisterStat(
+ new Stat(
+ "PacketsPoolCount",
+ "Objects within the packet pool",
+ "The number of objects currently stored within the packet pool",
+ "",
+ "clientstack",
+ "packetpool",
+ StatType.Pull,
+ stat => { lock (pool) { stat.Value = pool.Count; } },
+ StatVerbosity.Debug));
+
+ StatsManager.RegisterStat(
+ new Stat(
+ "PacketDataBlocksPoolCount",
+ "Objects within the packet data block pool",
+ "The number of objects currently stored within the packet data block pool",
+ "",
+ "clientstack",
+ "packetpool",
+ StatType.Pull,
+ stat => { lock (DataBlocks) { stat.Value = DataBlocks.Count; } },
+ StatVerbosity.Debug));
}
///
--
cgit v1.1
From 319ebaca06db3d4a38beff74725d321b7c836157 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Tue, 23 Oct 2012 02:44:15 +0100
Subject: Make it possible to turn the base UDP object packet pools on and off
whilst running via the "debug lludp pool " console command. For
debug purposes.
This does not currently apply to the higher LLUDP packetpool.
---
.../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 103 +++++++++++++++++----
.../ClientStack/Linden/UDP/OpenSimUDPBase.cs | 66 ++++++++-----
2 files changed, 131 insertions(+), 38 deletions(-)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index bcfd392..14cc863 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -170,6 +170,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private Pool m_incomingPacketPool;
+ private Stat m_incomingPacketPoolStat;
+
private int m_defaultRTO = 0;
private int m_maxRTO = 0;
private int m_ackTimeout = 0;
@@ -214,6 +216,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_circuitManager = circuitManager;
int sceneThrottleBps = 0;
+ bool usePools = false;
IConfig config = configSource.Configs["ClientStack.LindenUDP"];
if (config != null)
@@ -246,7 +249,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
PacketPool.Instance.RecyclePackets = packetConfig.GetBoolean("RecyclePackets", true);
PacketPool.Instance.RecycleDataBlocks = packetConfig.GetBoolean("RecycleDataBlocks", true);
- UsePools = packetConfig.GetBoolean("RecycleBaseUDPPackets", false);
+ usePools = packetConfig.GetBoolean("RecycleBaseUDPPackets", usePools);
}
#region BinaryStats
@@ -277,22 +280,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_throttle = new TokenBucket(null, sceneThrottleBps);
ThrottleRates = new ThrottleRates(configSource);
- if (UsePools)
- {
- m_incomingPacketPool = new Pool(() => new IncomingPacket(), 500);
-
- StatsManager.RegisterStat(
- new Stat(
- "IncomingPacketPoolCount",
- "Objects within incoming packet pool",
- "The number of objects currently stored within the incoming packet pool",
- "",
- "clientstack",
- "packetpool",
- StatType.Pull,
- stat => stat.Value = m_incomingPacketPool.Count,
- StatVerbosity.Debug));
- }
+ if (usePools)
+ EnablePools();
}
public void Start()
@@ -345,6 +334,50 @@ namespace OpenSim.Region.ClientStack.LindenUDP
base.StopInbound();
}
+ protected override bool EnablePools()
+ {
+ if (!UsePools)
+ {
+ base.EnablePools();
+
+ m_incomingPacketPool = new Pool(() => new IncomingPacket(), 500);
+
+ m_incomingPacketPoolStat
+ = new Stat(
+ "IncomingPacketPoolCount",
+ "Objects within incoming packet pool",
+ "The number of objects currently stored within the incoming packet pool",
+ "",
+ "clientstack",
+ "packetpool",
+ StatType.Pull,
+ stat => stat.Value = m_incomingPacketPool.Count,
+ StatVerbosity.Debug);
+
+ StatsManager.RegisterStat(m_incomingPacketPoolStat);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ protected override bool DisablePools()
+ {
+ if (UsePools)
+ {
+ base.DisablePools();
+
+ StatsManager.DeregisterStat(m_incomingPacketPoolStat);
+
+ // We won't null out the pool to avoid a race condition with code that may be in the middle of using it.
+
+ return true;
+ }
+
+ return false;
+ }
+
///
/// If the outgoing UDP thread times out, then return client that was being processed to help with debugging.
///
@@ -411,6 +444,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
MainConsole.Instance.Commands.AddCommand(
"Debug",
false,
+ "debug lludp pool",
+ "debug lludp pool ",
+ "Turn object pooling within the lludp component on or off.",
+ HandlePoolCommand);
+
+ MainConsole.Instance.Commands.AddCommand(
+ "Debug",
+ false,
"debug lludp status",
"debug lludp status",
"Return status of LLUDP packet processing.",
@@ -451,6 +492,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
StopOutbound();
}
+ private void HandlePoolCommand(string module, string[] args)
+ {
+ if (args.Length != 4)
+ {
+ MainConsole.Instance.Output("Usage: debug lludp pool ");
+ return;
+ }
+
+ string enabled = args[3];
+
+ if (enabled == "on")
+ {
+ if (EnablePools())
+ MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", m_scene.Name);
+ }
+ else if (enabled == "off")
+ {
+ if (DisablePools())
+ MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", m_scene.Name);
+ }
+ else
+ {
+ MainConsole.Instance.Output("Usage: debug lludp pool ");
+ }
+ }
+
private void HandleStatusCommand(string module, string[] args)
{
MainConsole.Instance.OutputFormat(
@@ -458,6 +525,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
MainConsole.Instance.OutputFormat(
"OUT LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningOutbound ? "enabled" : "disabled");
+
+ MainConsole.Instance.OutputFormat("LLUDP pools in {0} are {1}", m_scene.Name, UsePools ? "on" : "off");
}
public bool HandlesRegion(Location x)
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index 18abfd6..85cbb06 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
@@ -77,6 +77,8 @@ namespace OpenMetaverse
/// If IsRunningOut = false, then any request to send a packet is simply dropped.
public bool IsRunningOutbound { get; private set; }
+ private Stat m_poolCountStat;
+
///
/// Default constructor
///
@@ -107,27 +109,6 @@ namespace OpenMetaverse
/// necessary
public void StartInbound(int recvBufferSize, bool asyncPacketHandling)
{
- if (UsePools)
- {
- m_pool = new Pool(() => new UDPPacketBuffer(), 500);
-
- StatsManager.RegisterStat(
- new Stat(
- "UDPPacketBufferPoolCount",
- "Objects within the UDPPacketBuffer pool",
- "The number of objects currently stored within the UDPPacketBuffer pool",
- "",
- "clientstack",
- "packetpool",
- StatType.Pull,
- stat => stat.Value = m_pool.Count,
- StatVerbosity.Debug));
- }
- else
- {
- m_pool = null;
- }
-
m_asyncPacketHandling = asyncPacketHandling;
if (!IsRunningInbound)
@@ -197,6 +178,49 @@ namespace OpenMetaverse
IsRunningOutbound = false;
}
+ protected virtual bool EnablePools()
+ {
+ if (!UsePools)
+ {
+ m_pool = new Pool(() => new UDPPacketBuffer(), 500);
+
+ m_poolCountStat
+ = new Stat(
+ "UDPPacketBufferPoolCount",
+ "Objects within the UDPPacketBuffer pool",
+ "The number of objects currently stored within the UDPPacketBuffer pool",
+ "",
+ "clientstack",
+ "packetpool",
+ StatType.Pull,
+ stat => stat.Value = m_pool.Count,
+ StatVerbosity.Debug);
+
+ StatsManager.RegisterStat(m_poolCountStat);
+
+ UsePools = true;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ protected virtual bool DisablePools()
+ {
+ if (UsePools)
+ {
+ UsePools = false;
+ StatsManager.DeregisterStat(m_poolCountStat);
+
+ // We won't null out the pool to avoid a race condition with code that may be in the middle of using it.
+
+ return true;
+ }
+
+ return false;
+ }
+
private void AsyncBeginReceive()
{
UDPPacketBuffer buf;
--
cgit v1.1
From c13a99dc5cc82efac5497dab27dcb6b0d9865cea Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Thu, 25 Oct 2012 03:26:12 +0100
Subject: Fix script error messages not showing up in viewer 3 and associated
viewers.
Viewer 3 will discard such a message if the chat message owner does not match the avatar.
We were filling the ownerID with the primID, so this never matched, hence viewer 3 did not see any script error messages.
This commit fills the ownerID in with the prim ownerID so the script owner will receive script error messages.
This does not affect viewer 1 and associated viewers which continue to process script errors as normal.
---
OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 7427c59..8e5a6d2 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -817,8 +817,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
OutPacket(mov, ThrottleOutPacketType.Unknown);
}
- public void SendChatMessage(string message, byte type, Vector3 fromPos, string fromName,
- UUID fromAgentID, byte source, byte audible)
+ public void SendChatMessage(
+ string message, byte type, Vector3 fromPos, string fromName,
+ UUID fromAgentID, UUID ownerID, byte source, byte audible)
{
ChatFromSimulatorPacket reply = (ChatFromSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.ChatFromSimulator);
reply.ChatData.Audible = audible;
@@ -827,7 +828,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
reply.ChatData.SourceType = source;
reply.ChatData.Position = fromPos;
reply.ChatData.FromName = Util.StringToBytes256(fromName);
- reply.ChatData.OwnerID = fromAgentID;
+ reply.ChatData.OwnerID = ownerID;
reply.ChatData.SourceID = fromAgentID;
OutPacket(reply, ThrottleOutPacketType.Task);
--
cgit v1.1
From 4ba48151b232716ebb473bc320793a9610a96e5b Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 31 Oct 2012 00:39:45 +0000
Subject: Handle UUIDGroupName and ObjectGroup viewer UDP requests
asynchronously rather than synchronously.
This is to avoid the entire scene loop being held up when the group service is slow to respond.
There's no obvious reason for these queries to be sync rather than async.
---
OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 8e5a6d2..7382e09 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -5219,8 +5219,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false);
AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false);
AddLocalPacketHandler(PacketType.ParcelBuy, HandleParcelBuyRequest, false);
- AddLocalPacketHandler(PacketType.UUIDGroupNameRequest, HandleUUIDGroupNameRequest, false);
- AddLocalPacketHandler(PacketType.ObjectGroup, HandleObjectGroupRequest, false);
+ AddLocalPacketHandler(PacketType.UUIDGroupNameRequest, HandleUUIDGroupNameRequest);
+ AddLocalPacketHandler(PacketType.ObjectGroup, HandleObjectGroupRequest);
AddLocalPacketHandler(PacketType.GenericMessage, HandleGenericMessage);
AddLocalPacketHandler(PacketType.AvatarPropertiesRequest, HandleAvatarPropertiesRequest);
AddLocalPacketHandler(PacketType.ChatFromViewer, HandleChatFromViewer);
--
cgit v1.1
From cda127e30f0049cda21137363e4d759fd7fd4959 Mon Sep 17 00:00:00 2001
From: teravus
Date: Fri, 9 Nov 2012 23:55:30 -0500
Subject: * Prep work switching the GetMeshModule over to a poll service. *
This still has the image throttler in it.. as is... so it's not suitable
for live yet.... The throttler keeps track of the task throttle but doesn't
balance the UDP throttle yet.
---
.../ClientStack/Linden/Caps/GetMeshModule.cs | 362 ++++++++++++++++++++-
.../ClientStack/Linden/Caps/GetTextureModule.cs | 121 +++----
2 files changed, 410 insertions(+), 73 deletions(-)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
index 0d7b1fc..8deff81 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
@@ -27,11 +27,14 @@
using System;
using System.Collections;
+using System.Collections.Generic;
using System.Collections.Specialized;
using System.Reflection;
using System.IO;
+using System.Threading;
using System.Web;
using Mono.Addins;
+using OpenSim.Framework.Monitoring;
using log4net;
using Nini.Config;
using OpenMetaverse;
@@ -57,8 +60,42 @@ namespace OpenSim.Region.ClientStack.Linden
private IAssetService m_AssetService;
private bool m_Enabled = true;
private string m_URL;
+ struct aPollRequest
+ {
+ public PollServiceMeshEventArgs thepoll;
+ public UUID reqID;
+ public Hashtable request;
+ }
+
+ public class aPollResponse
+ {
+ public Hashtable response;
+ public int bytes;
+ }
+
+
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ private static GetMeshHandler m_getMeshHandler;
+
+ private IAssetService m_assetService = null;
+
+ private Dictionary m_capsDict = new Dictionary();
+ private static Thread[] m_workerThreads = null;
+
+ private static OpenMetaverse.BlockingQueue m_queue =
+ new OpenMetaverse.BlockingQueue();
+
+ private Dictionary m_pollservices = new Dictionary();
- #region IRegionModuleBase Members
+ #region ISharedRegionModule Members
+
+ ~GetMeshModule()
+ {
+ foreach (Thread t in m_workerThreads)
+ Watchdog.AbortThread(t.ManagedThreadId);
+
+ }
public Type ReplaceableInterface
{
@@ -83,6 +120,8 @@ namespace OpenSim.Region.ClientStack.Linden
return;
m_scene = pScene;
+
+ m_assetService = pScene.AssetService;
}
public void RemoveRegion(Scene scene)
@@ -91,6 +130,9 @@ namespace OpenSim.Region.ClientStack.Linden
return;
m_scene.EventManager.OnRegisterCaps -= RegisterCaps;
+ m_scene.EventManager.OnDeregisterCaps -= DeregisterCaps;
+ m_scene.EventManager.OnThrottleUpdate -= ThrottleUpdate;
+
m_scene = null;
}
@@ -101,6 +143,27 @@ namespace OpenSim.Region.ClientStack.Linden
m_AssetService = m_scene.RequestModuleInterface();
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
+ // We'll reuse the same handler for all requests.
+ m_getMeshHandler = new GetMeshHandler(m_assetService);
+ m_scene.EventManager.OnDeregisterCaps += DeregisterCaps;
+ m_scene.EventManager.OnThrottleUpdate += ThrottleUpdate;
+
+ if (m_workerThreads == null)
+ {
+ m_workerThreads = new Thread[2];
+
+ for (uint i = 0; i < 2; i++)
+ {
+ m_workerThreads[i] = Watchdog.StartThread(DoMeshRequests,
+ String.Format("MeshWorkerThread{0}", i),
+ ThreadPriority.Normal,
+ false,
+ false,
+ null,
+ int.MaxValue);
+ }
+ }
+
}
@@ -110,25 +173,209 @@ namespace OpenSim.Region.ClientStack.Linden
#endregion
+ private void DoMeshRequests()
+ {
+ while (true)
+ {
+ aPollRequest poolreq = m_queue.Dequeue();
+
+ poolreq.thepoll.Process(poolreq);
+ }
+ }
+
+ // Now we know when the throttle is changed by the client in the case of a root agent or by a neighbor region in the case of a child agent.
+ public void ThrottleUpdate(ScenePresence p)
+ {
+ byte[] throttles = p.ControllingClient.GetThrottlesPacked(1);
+ UUID user = p.UUID;
+ int imagethrottle = ExtractTaskThrottle(throttles);
+ PollServiceMeshEventArgs args;
+ if (m_pollservices.TryGetValue(user, out args))
+ {
+ args.UpdateThrottle(imagethrottle);
+ }
+ }
+
+ private int ExtractTaskThrottle(byte[] pthrottles)
+ {
+
+ byte[] adjData;
+ int pos = 0;
+
+ if (!BitConverter.IsLittleEndian)
+ {
+ byte[] newData = new byte[7 * 4];
+ Buffer.BlockCopy(pthrottles, 0, newData, 0, 7 * 4);
+
+ for (int i = 0; i < 7; i++)
+ Array.Reverse(newData, i * 4, 4);
+
+ adjData = newData;
+ }
+ else
+ {
+ adjData = pthrottles;
+ }
+
+ // 0.125f converts from bits to bytes
+ //int resend = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
+ //pos += 4;
+ // int land = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
+ //pos += 4;
+ // int wind = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
+ // pos += 4;
+ // int cloud = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
+ // pos += 4;
+ pos += 16;
+ int task = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
+ // pos += 4;
+ //int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); //pos += 4;
+ //int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f);
+ return task;
+ }
+
+ private class PollServiceMeshEventArgs : PollServiceEventArgs
+ {
+ private List requests =
+ new List();
+ private Dictionary responses =
+ new Dictionary();
+
+ private Scene m_scene;
+ private CapsDataThrottler m_throttler = new CapsDataThrottler(100000, 1400000, 10000);
+ public PollServiceMeshEventArgs(UUID pId, Scene scene) :
+ base(null, null, null, null, pId, int.MaxValue)
+ {
+ m_scene = scene;
+ // x is request id, y is userid
+ HasEvents = (x, y) =>
+ {
+ lock (responses)
+ {
+ bool ret = m_throttler.hasEvents(x, responses);
+ m_throttler.ProcessTime();
+ return ret;
+
+ }
+ };
+ GetEvents = (x, y) =>
+ {
+ lock (responses)
+ {
+ try
+ {
+ return responses[x].response;
+ }
+ finally
+ {
+ responses.Remove(x);
+ }
+ }
+ };
+ // x is request id, y is request data hashtable
+ Request = (x, y) =>
+ {
+ aPollRequest reqinfo = new aPollRequest();
+ reqinfo.thepoll = this;
+ reqinfo.reqID = x;
+ reqinfo.request = y;
+
+ m_queue.Enqueue(reqinfo);
+ };
+
+ // this should never happen except possible on shutdown
+ NoEvents = (x, y) =>
+ {
+ /*
+ lock (requests)
+ {
+ Hashtable request = requests.Find(id => id["RequestID"].ToString() == x.ToString());
+ requests.Remove(request);
+ }
+ */
+ Hashtable response = new Hashtable();
+
+ response["int_response_code"] = 500;
+ response["str_response_string"] = "Script timeout";
+ response["content_type"] = "text/plain";
+ response["keepalive"] = false;
+ response["reusecontext"] = false;
+
+ return response;
+ };
+ }
+
+ public void Process(aPollRequest requestinfo)
+ {
+ Hashtable response;
+
+ UUID requestID = requestinfo.reqID;
+
+ // If the avatar is gone, don't bother to get the texture
+ if (m_scene.GetScenePresence(Id) == null)
+ {
+ response = new Hashtable();
+
+ response["int_response_code"] = 500;
+ response["str_response_string"] = "Script timeout";
+ response["content_type"] = "text/plain";
+ response["keepalive"] = false;
+ response["reusecontext"] = false;
+
+ lock (responses)
+ responses[requestID] = new aPollResponse() { bytes = 0, response = response };
+
+ return;
+ }
+
+ response = m_getMeshHandler.Handle(requestinfo.request);
+ lock (responses)
+ {
+ responses[requestID] = new aPollResponse()
+ {
+ bytes = (int)response["int_bytes"],
+ response = response
+ };
+
+ }
+ m_throttler.ProcessTime();
+ }
+
+ internal void UpdateThrottle(int pimagethrottle)
+ {
+ m_throttler.ThrottleBytes = pimagethrottle;
+ }
+ }
public void RegisterCaps(UUID agentID, Caps caps)
{
// UUID capID = UUID.Random();
-
- //caps.RegisterHandler("GetTexture", new StreamHandler("GET", "/CAPS/" + capID, ProcessGetTexture));
if (m_URL == "localhost")
{
-// m_log.DebugFormat("[GETMESH]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
- GetMeshHandler gmeshHandler = new GetMeshHandler(m_AssetService);
- IRequestHandler reqHandler
- = new RestHTTPHandler(
- "GET",
- "/CAPS/" + UUID.Random(),
- httpMethod => gmeshHandler.ProcessGetMesh(httpMethod, UUID.Zero, null),
- "GetMesh",
- agentID.ToString());
+ string capUrl = "/CAPS/" + UUID.Random() + "/";
+
+ // Register this as a poll service
+ PollServiceMeshEventArgs args = new PollServiceMeshEventArgs(agentID, m_scene);
+
+ args.Type = PollServiceEventArgs.EventType.Mesh;
+ MainServer.Instance.AddPollServiceHTTPHandler(capUrl, args);
+
+ string hostName = m_scene.RegionInfo.ExternalHostName;
+ uint port = (MainServer.Instance == null) ? 0 : MainServer.Instance.Port;
+ string protocol = "http";
- caps.RegisterHandler("GetMesh", reqHandler);
+ if (MainServer.Instance.UseSSL)
+ {
+ hostName = MainServer.Instance.SSLCommonName;
+ port = MainServer.Instance.SSLPort;
+ protocol = "https";
+ }
+ caps.RegisterHandler("GetMesh", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
+ m_pollservices.Add(agentID, args);
+ m_capsDict[agentID] = capUrl;
+
+
+
}
else
{
@@ -136,6 +383,95 @@ namespace OpenSim.Region.ClientStack.Linden
caps.RegisterHandler("GetMesh", m_URL);
}
}
+ private void DeregisterCaps(UUID agentID, Caps caps)
+ {
+ string capUrl;
+ PollServiceMeshEventArgs args;
+ if (m_capsDict.TryGetValue(agentID, out capUrl))
+ {
+ MainServer.Instance.RemoveHTTPHandler("", capUrl);
+ m_capsDict.Remove(agentID);
+ }
+ if (m_pollservices.TryGetValue(agentID, out args))
+ {
+ m_pollservices.Remove(agentID);
+ }
+ }
+
+ internal sealed class CapsDataThrottler
+ {
+
+ private volatile int currenttime = 0;
+ private volatile int lastTimeElapsed = 0;
+ private volatile int BytesSent = 0;
+ private int oversizedImages = 0;
+ public CapsDataThrottler(int pBytes, int max, int min)
+ {
+ ThrottleBytes = pBytes;
+ lastTimeElapsed = Util.EnvironmentTickCount();
+ }
+ public bool hasEvents(UUID key, Dictionary responses)
+ {
+ PassTime();
+ // Note, this is called IN LOCK
+ bool haskey = responses.ContainsKey(key);
+ if (!haskey)
+ {
+ return false;
+ }
+ aPollResponse response;
+ if (responses.TryGetValue(key, out response))
+ {
+
+ // Normal
+ if (BytesSent + response.bytes <= ThrottleBytes)
+ {
+ BytesSent += response.bytes;
+ //TimeBasedAction timeBasedAction = new TimeBasedAction { byteRemoval = response.bytes, requestId = key, timeMS = currenttime + 1000, unlockyn = false };
+ //m_actions.Add(timeBasedAction);
+ return true;
+ }
+ // Big textures
+ else if (response.bytes > ThrottleBytes && oversizedImages <= ((ThrottleBytes % 50000) + 1))
+ {
+ Interlocked.Increment(ref oversizedImages);
+ BytesSent += response.bytes;
+ //TimeBasedAction timeBasedAction = new TimeBasedAction { byteRemoval = response.bytes, requestId = key, timeMS = currenttime + (((response.bytes % ThrottleBytes)+1)*1000) , unlockyn = false };
+ //m_actions.Add(timeBasedAction);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ return haskey;
+ }
+ public void ProcessTime()
+ {
+ PassTime();
+ }
+
+
+ private void PassTime()
+ {
+ currenttime = Util.EnvironmentTickCount();
+ int timeElapsed = Util.EnvironmentTickCountSubtract(currenttime, lastTimeElapsed);
+ //processTimeBasedActions(responses);
+ if (Util.EnvironmentTickCountSubtract(currenttime, timeElapsed) >= 1000)
+ {
+ lastTimeElapsed = Util.EnvironmentTickCount();
+ BytesSent -= ThrottleBytes;
+ if (BytesSent < 0) BytesSent = 0;
+ if (BytesSent < ThrottleBytes)
+ {
+ oversizedImages = 0;
+ }
+ }
+ }
+ public int ThrottleBytes;
+ }
}
}
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
index 8cba6c8..c8c709a 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs
@@ -364,80 +364,81 @@ namespace OpenSim.Region.ClientStack.Linden
poolreq.thepoll.Process(poolreq);
}
}
- }
-
- internal sealed class CapsDataThrottler
- {
-
- private volatile int currenttime = 0;
- private volatile int lastTimeElapsed = 0;
- private volatile int BytesSent = 0;
- private int oversizedImages = 0;
- public CapsDataThrottler(int pBytes, int max, int min)
- {
- ThrottleBytes = pBytes;
- lastTimeElapsed = Util.EnvironmentTickCount();
- }
- public bool hasEvents(UUID key, Dictionary responses)
+ internal sealed class CapsDataThrottler
{
- PassTime();
- // Note, this is called IN LOCK
- bool haskey = responses.ContainsKey(key);
- if (!haskey)
+
+ private volatile int currenttime = 0;
+ private volatile int lastTimeElapsed = 0;
+ private volatile int BytesSent = 0;
+ private int oversizedImages = 0;
+ public CapsDataThrottler(int pBytes, int max, int min)
{
- return false;
+ ThrottleBytes = pBytes;
+ lastTimeElapsed = Util.EnvironmentTickCount();
}
- GetTextureModule.aPollResponse response;
- if (responses.TryGetValue(key,out response))
+ public bool hasEvents(UUID key, Dictionary responses)
{
-
- // Normal
- if (BytesSent + response.bytes <= ThrottleBytes)
+ PassTime();
+ // Note, this is called IN LOCK
+ bool haskey = responses.ContainsKey(key);
+ if (!haskey)
{
- BytesSent += response.bytes;
- //TimeBasedAction timeBasedAction = new TimeBasedAction { byteRemoval = response.bytes, requestId = key, timeMS = currenttime + 1000, unlockyn = false };
- //m_actions.Add(timeBasedAction);
- return true;
- }
- // Big textures
- else if (response.bytes > ThrottleBytes && oversizedImages <= ((ThrottleBytes%50000) + 1))
- {
- Interlocked.Increment(ref oversizedImages);
- BytesSent += response.bytes;
- //TimeBasedAction timeBasedAction = new TimeBasedAction { byteRemoval = response.bytes, requestId = key, timeMS = currenttime + (((response.bytes % ThrottleBytes)+1)*1000) , unlockyn = false };
- //m_actions.Add(timeBasedAction);
- return true;
+ return false;
}
- else
+ GetTextureModule.aPollResponse response;
+ if (responses.TryGetValue(key, out response))
{
- return false;
+
+ // Normal
+ if (BytesSent + response.bytes <= ThrottleBytes)
+ {
+ BytesSent += response.bytes;
+ //TimeBasedAction timeBasedAction = new TimeBasedAction { byteRemoval = response.bytes, requestId = key, timeMS = currenttime + 1000, unlockyn = false };
+ //m_actions.Add(timeBasedAction);
+ return true;
+ }
+ // Big textures
+ else if (response.bytes > ThrottleBytes && oversizedImages <= ((ThrottleBytes % 50000) + 1))
+ {
+ Interlocked.Increment(ref oversizedImages);
+ BytesSent += response.bytes;
+ //TimeBasedAction timeBasedAction = new TimeBasedAction { byteRemoval = response.bytes, requestId = key, timeMS = currenttime + (((response.bytes % ThrottleBytes)+1)*1000) , unlockyn = false };
+ //m_actions.Add(timeBasedAction);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
}
+
+ return haskey;
+ }
+ public void ProcessTime()
+ {
+ PassTime();
}
- return haskey;
- }
- public void ProcessTime()
- {
- PassTime();
- }
-
-
- private void PassTime()
- {
- currenttime = Util.EnvironmentTickCount();
- int timeElapsed = Util.EnvironmentTickCountSubtract(currenttime, lastTimeElapsed);
- //processTimeBasedActions(responses);
- if (Util.EnvironmentTickCountSubtract(currenttime, timeElapsed) >= 1000)
+
+ private void PassTime()
{
- lastTimeElapsed = Util.EnvironmentTickCount();
- BytesSent -= ThrottleBytes;
- if (BytesSent < 0) BytesSent = 0;
- if (BytesSent < ThrottleBytes)
+ currenttime = Util.EnvironmentTickCount();
+ int timeElapsed = Util.EnvironmentTickCountSubtract(currenttime, lastTimeElapsed);
+ //processTimeBasedActions(responses);
+ if (Util.EnvironmentTickCountSubtract(currenttime, timeElapsed) >= 1000)
{
- oversizedImages = 0;
+ lastTimeElapsed = Util.EnvironmentTickCount();
+ BytesSent -= ThrottleBytes;
+ if (BytesSent < 0) BytesSent = 0;
+ if (BytesSent < ThrottleBytes)
+ {
+ oversizedImages = 0;
+ }
}
}
+ public int ThrottleBytes;
}
- public int ThrottleBytes;
}
+
+
}
--
cgit v1.1
From e9153e1d1aae50024d8cd05fe14a9bce34343a0e Mon Sep 17 00:00:00 2001
From: teravus
Date: Thu, 15 Nov 2012 10:05:16 -0500
Subject: Revert "Merge master into teravuswork", it should have been
avination, not master.
This reverts commit dfac269032300872c4d0dc507f4f9062d102b0f4, reversing
changes made to 619c39e5144f15aca129d6d999bcc5c34133ee64.
---
.../Linden/Caps/BunchOfCaps/BunchOfCaps.cs | 9 +-
.../Linden/Caps/EventQueue/EventQueueGetModule.cs | 21 +-
.../Caps/EventQueue/Tests/EventQueueTests.cs | 2 +-
.../ClientStack/Linden/Caps/RegionConsoleModule.cs | 2 +-
.../ClientStack/Linden/UDP/IncomingPacket.cs | 7 +-
.../Region/ClientStack/Linden/UDP/LLClientView.cs | 169 ++++-------
.../Region/ClientStack/Linden/UDP/LLUDPServer.cs | 338 +++------------------
.../ClientStack/Linden/UDP/OpenSimUDPBase.cs | 116 ++-----
.../Region/ClientStack/Linden/UDP/PacketPool.cs | 316 -------------------
.../Linden/UDP/Tests/BasicCircuitTests.cs | 7 +-
10 files changed, 164 insertions(+), 823 deletions(-)
delete mode 100644 OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
index f6146a9..650cd50 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/BunchOfCaps.cs
@@ -241,8 +241,8 @@ namespace OpenSim.Region.ClientStack.Linden
m_HostCapsObj.RegisterHandler(
"SEED", new RestStreamHandler("POST", capsBase + m_requestPath, SeedCapRequest, "SEED", null));
-// m_log.DebugFormat(
-// "[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_HostCapsObj.AgentID);
+ m_log.DebugFormat(
+ "[CAPS]: Registered seed capability {0} for {1}", capsBase + m_requestPath, m_HostCapsObj.AgentID);
//m_capsHandlers["MapLayer"] =
// new LLSDStreamhandler("POST",
@@ -337,12 +337,11 @@ namespace OpenSim.Region.ClientStack.Linden
public string SeedCapRequest(string request, string path, string param,
IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{
- m_log.DebugFormat(
- "[CAPS]: Received SEED caps request in {0} for agent {1}", m_regionName, m_HostCapsObj.AgentID);
+// m_log.Debug("[CAPS]: Seed Caps Request in region: " + m_regionName);
if (!m_Scene.CheckClient(m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint))
{
- m_log.WarnFormat(
+ m_log.DebugFormat(
"[CAPS]: Unauthorized CAPS client {0} from {1}",
m_HostCapsObj.AgentID, httpRequest.RemoteIPEndPoint);
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
index 5bbdce8..e113c60 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/EventQueueGetModule.cs
@@ -94,7 +94,7 @@ namespace OpenSim.Region.ClientStack.Linden
//scene.CommsManager.HttpServer.AddLLSDHandler("/CAPS/EQG/", EventQueueFallBack);
-// scene.EventManager.OnNewClient += OnNewClient;
+ scene.EventManager.OnNewClient += OnNewClient;
// TODO: Leaving these open, or closing them when we
// become a child is incorrect. It messes up TP in a big
@@ -102,7 +102,6 @@ namespace OpenSim.Region.ClientStack.Linden
// circuit is there.
scene.EventManager.OnClientClosed += ClientClosed;
-
scene.EventManager.OnMakeChildAgent += MakeChildAgent;
scene.EventManager.OnRegisterCaps += OnRegisterCaps;
@@ -111,10 +110,10 @@ namespace OpenSim.Region.ClientStack.Linden
false,
"debug eq",
"debug eq [0|1|2]",
- "Turn on event queue debugging\n"
- + " <= 0 - turns off all event queue logging\n"
- + " >= 1 - turns on outgoing event logging\n"
- + " >= 2 - turns on poll notification",
+ "Turn on event queue debugging"
+ + "<= 0 - turns off all event queue logging"
+ + ">= 1 - turns on outgoing event logging"
+ + ">= 2 - turns on poll notification",
HandleDebugEq);
}
else
@@ -227,6 +226,16 @@ namespace OpenSim.Region.ClientStack.Linden
#endregion
+ private void OnNewClient(IClientAPI client)
+ {
+ //client.OnLogout += ClientClosed;
+ }
+
+// private void ClientClosed(IClientAPI client)
+// {
+// ClientClosed(client.AgentId);
+// }
+
private void ClientClosed(UUID agentID, Scene scene)
{
// m_log.DebugFormat("[EVENTQUEUE]: Closed client {0} in region {1}", agentID, m_scene.RegionInfo.RegionName);
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
index d604cf6..cd70410 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/EventQueue/Tests/EventQueueTests.cs
@@ -94,7 +94,7 @@ namespace OpenSim.Region.ClientStack.Linden.Tests
UUID spId = TestHelpers.ParseTail(0x1);
SceneHelpers.AddScenePresence(m_scene, spId);
- m_scene.IncomingCloseAgent(spId, false);
+ m_scene.IncomingCloseAgent(spId);
// TODO: Add more assertions for the other aspects of event queues
Assert.That(MainServer.Instance.GetPollServiceHandlerKeys().Count, Is.EqualTo(0));
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs
index fcac182..0a5ad0f 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/RegionConsoleModule.cs
@@ -109,7 +109,7 @@ namespace OpenSim.Region.ClientStack.Linden
UUID capID = UUID.Random();
-// m_log.DebugFormat("[REGION CONSOLE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
+ m_log.DebugFormat("[REGION CONSOLE]: /CAPS/{0} in region {1}", capID, m_scene.RegionInfo.RegionName);
caps.RegisterHandler(
"SimConsoleAsync",
new ConsoleHandler("/CAPS/" + capID + "/", "SimConsoleAsync", agentID, this, m_scene));
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs b/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs
index e22670b..1b8535c 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/IncomingPacket.cs
@@ -45,12 +45,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public Packet Packet;
///
- /// No arg constructor.
- ///
- public IncomingPacket() {}
-
- ///
- /// Constructor
+ /// Default constructor
///
/// Reference to the client this packet came from
/// Packet data
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index c9aa4ca..ae9ed7f 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -47,7 +47,6 @@ using OpenSim.Region.Framework.Scenes;
using OpenSim.Services.Interfaces;
using Timer = System.Timers.Timer;
using AssetLandmark = OpenSim.Framework.AssetLandmark;
-using RegionFlags = OpenMetaverse.RegionFlags;
using Nini.Config;
using System.IO;
@@ -356,17 +355,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private bool m_deliverPackets = true;
private int m_animationSequenceNumber = 1;
private bool m_SendLogoutPacketWhenClosing = true;
-
- ///
- /// We retain a single AgentUpdateArgs so that we can constantly reuse it rather than construct a new one for
- /// every single incoming AgentUpdate. Every client sends 10 AgentUpdate UDP messages per second, even if it
- /// is doing absolutely nothing.
- ///
- ///
- /// This does mean that agent updates must be processed synchronously, at least for each client, and called methods
- /// cannot retain a reference to it outside of that method.
- ///
- private AgentUpdateArgs m_lastAgentUpdateArgs;
+ private AgentUpdateArgs lastarg;
protected Dictionary m_packetHandlers = new Dictionary();
protected Dictionary m_genericPacketHandlers = new Dictionary(); //PauPaw:Local Generic Message handlers
@@ -521,18 +510,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
///
public void Close()
{
- Close(true, false);
+ Close(true);
}
- public void Close(bool sendStop, bool force)
+ ///
+ /// Shut down the client view
+ ///
+ public void Close(bool sendStop)
{
// We lock here to prevent race conditions between two threads calling close simultaneously (e.g.
// a simultaneous relog just as a client is being closed out due to no packet ack from the old connection.
lock (CloseSyncLock)
{
- // We still perform a force close inside the sync lock since this is intended to attempt close where
- // there is some unidentified connection problem, not where we have issues due to deadlock
- if (!IsActive && !force)
+ if (!IsActive)
return;
IsActive = false;
@@ -847,9 +837,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
OutPacket(mov, ThrottleOutPacketType.Unknown);
}
- public void SendChatMessage(
- string message, byte type, Vector3 fromPos, string fromName,
- UUID fromAgentID, UUID ownerID, byte source, byte audible)
+ public void SendChatMessage(string message, byte type, Vector3 fromPos, string fromName,
+ UUID fromAgentID, byte source, byte audible)
{
ChatFromSimulatorPacket reply = (ChatFromSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.ChatFromSimulator);
reply.ChatData.Audible = audible;
@@ -858,7 +847,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
reply.ChatData.SourceType = source;
reply.ChatData.Position = fromPos;
reply.ChatData.FromName = Util.StringToBytes256(fromName);
- reply.ChatData.OwnerID = ownerID;
+ reply.ChatData.OwnerID = fromAgentID;
reply.ChatData.SourceID = fromAgentID;
OutPacket(reply, ThrottleOutPacketType.Unknown);
@@ -3996,8 +3985,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
List blocks = terseAgentUpdateBlocks.Value;
- ImprovedTerseObjectUpdatePacket packet
- = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
+ ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
packet.RegionData.TimeDilation = timeDilation;
packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
@@ -4042,9 +4030,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
List blocks = terseUpdateBlocks.Value;
- ImprovedTerseObjectUpdatePacket packet
- = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
- PacketType.ImprovedTerseObjectUpdate);
+ ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
packet.RegionData.TimeDilation = timeDilation;
packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count];
@@ -4052,7 +4038,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
for (int i = 0; i < blocks.Count; i++)
packet.ObjectData[i] = blocks[i];
- OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
+ OutPacket(packet, ThrottleOutPacketType.Task, true);
}
#endregion Packet Sending
@@ -4549,7 +4535,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
returnblock[j] = new EstateOwnerMessagePacket.ParamListBlock();
}
- j = 0;
+ j = 0;
returnblock[j].Parameter = Utils.StringToBytes(estateID.ToString()); j++;
returnblock[j].Parameter = Utils.StringToBytes(((int)Constants.EstateAccessCodex.EstateBans).ToString()); j++;
@@ -5053,9 +5039,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Y, -64.0f, 64.0f), data, pos); pos += 2;
Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Z, -64.0f, 64.0f), data, pos); pos += 2;
- ImprovedTerseObjectUpdatePacket.ObjectDataBlock block
- = PacketPool.Instance.GetDataBlock();
-
+ ImprovedTerseObjectUpdatePacket.ObjectDataBlock block = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock();
block.Data = data;
if (textureEntry != null && textureEntry.Length > 0)
@@ -5305,18 +5289,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
protected virtual void RegisterLocalPacketHandlers()
{
AddLocalPacketHandler(PacketType.LogoutRequest, HandleLogout);
-
- // If AgentUpdate is ever handled asynchronously, then we will also need to construct a new AgentUpdateArgs
- // for each AgentUpdate packet.
AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false);
-
AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false);
AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false);
AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false);
AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false);
AddLocalPacketHandler(PacketType.ParcelBuy, HandleParcelBuyRequest, false);
- AddLocalPacketHandler(PacketType.UUIDGroupNameRequest, HandleUUIDGroupNameRequest);
- AddLocalPacketHandler(PacketType.ObjectGroup, HandleObjectGroupRequest);
+ AddLocalPacketHandler(PacketType.UUIDGroupNameRequest, HandleUUIDGroupNameRequest, false);
+ AddLocalPacketHandler(PacketType.ObjectGroup, HandleObjectGroupRequest, false);
AddLocalPacketHandler(PacketType.GenericMessage, HandleGenericMessage);
AddLocalPacketHandler(PacketType.AvatarPropertiesRequest, HandleAvatarPropertiesRequest);
AddLocalPacketHandler(PacketType.ChatFromViewer, HandleChatFromViewer);
@@ -5538,84 +5518,81 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#region Scene/Avatar
- private bool HandleAgentUpdate(IClientAPI sener, Packet packet)
+ private bool HandleAgentUpdate(IClientAPI sener, Packet Pack)
{
if (OnAgentUpdate != null)
{
- AgentUpdatePacket agentUpdate = (AgentUpdatePacket)packet;
+ bool update = false;
+ AgentUpdatePacket agenUpdate = (AgentUpdatePacket)Pack;
#region Packet Session and User Check
- if (agentUpdate.AgentData.SessionID != SessionId || agentUpdate.AgentData.AgentID != AgentId)
- {
- PacketPool.Instance.ReturnPacket(packet);
+ if (agenUpdate.AgentData.SessionID != SessionId || agenUpdate.AgentData.AgentID != AgentId)
return false;
- }
#endregion
- bool update = false;
- AgentUpdatePacket.AgentDataBlock x = agentUpdate.AgentData;
+ AgentUpdatePacket.AgentDataBlock x = agenUpdate.AgentData;
+
+ // We can only check when we have something to check
+ // against.
- if (m_lastAgentUpdateArgs != null)
+ if (lastarg != null)
{
- // These should be ordered from most-likely to
- // least likely to change. I've made an initial
- // guess at that.
update =
(
- (x.BodyRotation != m_lastAgentUpdateArgs.BodyRotation) ||
- (x.CameraAtAxis != m_lastAgentUpdateArgs.CameraAtAxis) ||
- (x.CameraCenter != m_lastAgentUpdateArgs.CameraCenter) ||
- (x.CameraLeftAxis != m_lastAgentUpdateArgs.CameraLeftAxis) ||
- (x.CameraUpAxis != m_lastAgentUpdateArgs.CameraUpAxis) ||
- (x.ControlFlags != m_lastAgentUpdateArgs.ControlFlags) ||
+ (x.BodyRotation != lastarg.BodyRotation) ||
+ (x.CameraAtAxis != lastarg.CameraAtAxis) ||
+ (x.CameraCenter != lastarg.CameraCenter) ||
+ (x.CameraLeftAxis != lastarg.CameraLeftAxis) ||
+ (x.CameraUpAxis != lastarg.CameraUpAxis) ||
+ (x.ControlFlags != lastarg.ControlFlags) ||
(x.ControlFlags != 0) ||
- (x.Far != m_lastAgentUpdateArgs.Far) ||
- (x.Flags != m_lastAgentUpdateArgs.Flags) ||
- (x.State != m_lastAgentUpdateArgs.State) ||
- (x.HeadRotation != m_lastAgentUpdateArgs.HeadRotation) ||
- (x.SessionID != m_lastAgentUpdateArgs.SessionID) ||
- (x.AgentID != m_lastAgentUpdateArgs.AgentID)
+ (x.Far != lastarg.Far) ||
+ (x.Flags != lastarg.Flags) ||
+ (x.State != lastarg.State) ||
+ (x.HeadRotation != lastarg.HeadRotation) ||
+ (x.SessionID != lastarg.SessionID) ||
+ (x.AgentID != lastarg.AgentID)
);
}
else
{
- m_lastAgentUpdateArgs = new AgentUpdateArgs();
update = true;
}
+ // These should be ordered from most-likely to
+ // least likely to change. I've made an initial
+ // guess at that.
+
if (update)
{
// m_log.DebugFormat("[LLCLIENTVIEW]: Triggered AgentUpdate for {0}", sener.Name);
- m_lastAgentUpdateArgs.AgentID = x.AgentID;
- m_lastAgentUpdateArgs.BodyRotation = x.BodyRotation;
- m_lastAgentUpdateArgs.CameraAtAxis = x.CameraAtAxis;
- m_lastAgentUpdateArgs.CameraCenter = x.CameraCenter;
- m_lastAgentUpdateArgs.CameraLeftAxis = x.CameraLeftAxis;
- m_lastAgentUpdateArgs.CameraUpAxis = x.CameraUpAxis;
- m_lastAgentUpdateArgs.ControlFlags = x.ControlFlags;
- m_lastAgentUpdateArgs.Far = x.Far;
- m_lastAgentUpdateArgs.Flags = x.Flags;
- m_lastAgentUpdateArgs.HeadRotation = x.HeadRotation;
- m_lastAgentUpdateArgs.SessionID = x.SessionID;
- m_lastAgentUpdateArgs.State = x.State;
-
+ AgentUpdateArgs arg = new AgentUpdateArgs();
+ arg.AgentID = x.AgentID;
+ arg.BodyRotation = x.BodyRotation;
+ arg.CameraAtAxis = x.CameraAtAxis;
+ arg.CameraCenter = x.CameraCenter;
+ arg.CameraLeftAxis = x.CameraLeftAxis;
+ arg.CameraUpAxis = x.CameraUpAxis;
+ arg.ControlFlags = x.ControlFlags;
+ arg.Far = x.Far;
+ arg.Flags = x.Flags;
+ arg.HeadRotation = x.HeadRotation;
+ arg.SessionID = x.SessionID;
+ arg.State = x.State;
UpdateAgent handlerAgentUpdate = OnAgentUpdate;
UpdateAgent handlerPreAgentUpdate = OnPreAgentUpdate;
-
+ lastarg = arg; // save this set of arguments for nexttime
if (handlerPreAgentUpdate != null)
- OnPreAgentUpdate(this, m_lastAgentUpdateArgs);
-
+ OnPreAgentUpdate(this, arg);
if (handlerAgentUpdate != null)
- OnAgentUpdate(this, m_lastAgentUpdateArgs);
+ OnAgentUpdate(this, arg);
handlerAgentUpdate = null;
handlerPreAgentUpdate = null;
}
}
- PacketPool.Instance.ReturnPacket(packet);
-
return true;
}
@@ -5987,8 +5964,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
msgpack.MessageBlock.ID,
msgpack.MessageBlock.Offline != 0 ? true : false,
msgpack.MessageBlock.Position,
- msgpack.MessageBlock.BinaryBucket,
- true);
+ msgpack.MessageBlock.BinaryBucket);
handlerInstantMessage(this, im);
}
@@ -9275,9 +9251,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
#endregion
- string method = Utils.BytesToString(messagePacket.MethodData.Method);
-
- switch (method)
+ switch (Utils.BytesToString(messagePacket.MethodData.Method))
{
case "getinfo":
if (((Scene)m_scene).Permissions.CanIssueEstateCommand(AgentId, false))
@@ -9593,17 +9567,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return true;
default:
- m_log.WarnFormat(
- "[LLCLIENTVIEW]: EstateOwnerMessage: Unknown method {0} requested for {1} in {2}",
- method, Name, Scene.Name);
-
- for (int i = 0; i < messagePacket.ParamList.Length; i++)
- {
- EstateOwnerMessagePacket.ParamListBlock block = messagePacket.ParamList[i];
- string data = (string)Utils.BytesToString(block.Parameter);
- m_log.DebugFormat("[LLCLIENTVIEW]: Param {0}={1}", i, data);
- }
-
+ m_log.Error("EstateOwnerMessage: Unknown method requested\n" + messagePacket);
return true;
}
@@ -11996,7 +11960,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
logPacket = false;
if (DebugPacketLevel <= 50
- && (packet.Type == PacketType.ImprovedTerseObjectUpdate || packet.Type == PacketType.ObjectUpdate))
+ & (packet.Type == PacketType.ImprovedTerseObjectUpdate || packet.Type == PacketType.ObjectUpdate))
logPacket = false;
if (DebugPacketLevel <= 25 && packet.Type == PacketType.ObjectPropertiesFamily)
@@ -12070,6 +12034,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (!ProcessPacketMethod(packet))
m_log.Warn("[CLIENT]: unhandled packet " + packet.Type);
+
+ PacketPool.Instance.ReturnPacket(packet);
}
private static PrimitiveBaseShape GetShapeFromAddPacket(ObjectAddPacket addPacket)
@@ -12238,7 +12204,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
Kick(reason);
Thread.Sleep(1000);
- Disconnect();
+ Close();
}
public void Disconnect()
@@ -12526,10 +12492,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
ushort timeDilation = Utils.FloatToUInt16(TIME_DILATION, 0.0f, 1.0f);
- ImprovedTerseObjectUpdatePacket packet
- = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
- PacketType.ImprovedTerseObjectUpdate);
-
+ ImprovedTerseObjectUpdatePacket packet = new ImprovedTerseObjectUpdatePacket();
packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
packet.RegionData.TimeDilation = timeDilation;
packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index b8951d9..d6513c5 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -37,7 +37,6 @@ using log4net;
using Nini.Config;
using OpenMetaverse.Packets;
using OpenSim.Framework;
-using OpenSim.Framework.Console;
using OpenSim.Framework.Monitoring;
using OpenSim.Region.Framework.Scenes;
using OpenMetaverse;
@@ -101,11 +100,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// The measured resolution of Environment.TickCount
public readonly float TickCountResolution;
-
/// Number of prim updates to put on the queue each time the
/// OnQueueEmpty event is triggered for updates
public readonly int PrimUpdatesPerCallback;
-
/// Number of texture packets to put on the queue each time the
/// OnQueueEmpty event is triggered for textures
public readonly int TextureSendLimit;
@@ -127,37 +124,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// Manages authentication for agent circuits
private AgentCircuitManager m_circuitManager;
-
/// Reference to the scene this UDP server is attached to
protected Scene m_scene;
-
/// The X/Y coordinates of the scene this UDP server is attached to
private Location m_location;
-
/// The size of the receive buffer for the UDP socket. This value
/// is passed up to the operating system and used in the system networking
/// stack. Use zero to leave this value as the default
private int m_recvBufferSize;
-
/// Flag to process packets asynchronously or synchronously
private bool m_asyncPacketHandling;
-
/// Tracks whether or not a packet was sent each round so we know
/// whether or not to sleep
private bool m_packetSent;
/// Environment.TickCount of the last time that packet stats were reported to the scene
private int m_elapsedMSSinceLastStatReport = 0;
-
/// Environment.TickCount of the last time the outgoing packet handler executed
private int m_tickLastOutgoingPacketHandler;
-
/// Keeps track of the number of elapsed milliseconds since the last time the outgoing packet handler looped
private int m_elapsedMSOutgoingPacketHandler;
-
/// Keeps track of the number of 100 millisecond periods elapsed in the outgoing packet handler executed
private int m_elapsed100MSOutgoingPacketHandler;
-
/// Keeps track of the number of 500 millisecond periods elapsed in the outgoing packet handler executed
private int m_elapsed500MSOutgoingPacketHandler;
@@ -171,9 +159,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
protected bool m_sendPing;
private ExpiringCache> m_pendingCache = new ExpiringCache>();
- private Pool m_incomingPacketPool;
-
- private Stat m_incomingPacketPoolStat;
private int m_defaultRTO = 0;
private int m_maxRTO = 0;
@@ -195,9 +180,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
///
private IClientAPI m_currentIncomingClient;
- public LLUDPServer(
- IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port,
- IConfigSource configSource, AgentCircuitManager circuitManager)
+ public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager)
: base(listenIP, (int)port)
{
#region Environment.TickCount Measurement
@@ -219,7 +202,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_circuitManager = circuitManager;
int sceneThrottleBps = 0;
- bool usePools = false;
IConfig config = configSource.Configs["ClientStack.LindenUDP"];
if (config != null)
@@ -245,16 +227,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_pausedAckTimeout = 1000 * 300; // 5 minutes
}
- // FIXME: This actually only needs to be done once since the PacketPool is shared across all servers.
- // However, there is no harm in temporarily doing it multiple times.
- IConfig packetConfig = configSource.Configs["PacketPool"];
- if (packetConfig != null)
- {
- PacketPool.Instance.RecyclePackets = packetConfig.GetBoolean("RecyclePackets", true);
- PacketPool.Instance.RecycleDataBlocks = packetConfig.GetBoolean("RecycleDataBlocks", true);
- usePools = packetConfig.GetBoolean("RecycleBaseUDPPackets", usePools);
- }
-
#region BinaryStats
config = configSource.Configs["Statistics.Binary"];
m_shouldCollectStats = false;
@@ -282,28 +254,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_throttle = new TokenBucket(null, sceneThrottleBps);
ThrottleRates = new ThrottleRates(configSource);
-
- if (usePools)
- EnablePools();
}
public void Start()
{
- StartInbound();
- StartOutbound();
+ if (m_scene == null)
+ throw new InvalidOperationException("[LLUDPSERVER]: Cannot LLUDPServer.Start() without an IScene reference");
- m_elapsedMSSinceLastStatReport = Environment.TickCount;
- }
-
- private void StartInbound()
- {
m_log.InfoFormat(
- "[LLUDPSERVER]: Starting inbound packet processing for the LLUDP server in {0} mode with UsePools = {1}",
- m_asyncPacketHandling ? "asynchronous" : "synchronous", UsePools);
+ "[LLUDPSERVER]: Starting the LLUDP server in {0} mode",
+ m_asyncPacketHandling ? "asynchronous" : "synchronous");
- base.StartInbound(m_recvBufferSize, m_asyncPacketHandling);
+ base.Start(m_recvBufferSize, m_asyncPacketHandling);
- // This thread will process the packets received that are placed on the packetInbox
+ // Start the packet processing threads
Watchdog.StartThread(
IncomingPacketHandler,
string.Format("Incoming Packets ({0})", m_scene.RegionInfo.RegionName),
@@ -312,13 +276,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
true,
GetWatchdogIncomingAlarmData,
Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS);
- }
-
- private new void StartOutbound()
- {
- m_log.Info("[LLUDPSERVER]: Starting outbound packet processing for the LLUDP server");
-
- base.StartOutbound();
Watchdog.StartThread(
OutgoingPacketHandler,
@@ -328,57 +285,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
true,
GetWatchdogOutgoingAlarmData,
Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS);
- }
-
- public void Stop()
- {
- m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName);
- base.StopOutbound();
- base.StopInbound();
- }
- protected override bool EnablePools()
- {
- if (!UsePools)
- {
- base.EnablePools();
-
- m_incomingPacketPool = new Pool(() => new IncomingPacket(), 500);
-
- m_incomingPacketPoolStat
- = new Stat(
- "IncomingPacketPoolCount",
- "Objects within incoming packet pool",
- "The number of objects currently stored within the incoming packet pool",
- "",
- "clientstack",
- "packetpool",
- StatType.Pull,
- stat => stat.Value = m_incomingPacketPool.Count,
- StatVerbosity.Debug);
-
- StatsManager.RegisterStat(m_incomingPacketPoolStat);
-
- return true;
- }
-
- return false;
- }
-
- protected override bool DisablePools()
- {
- if (UsePools)
- {
- base.DisablePools();
-
- StatsManager.DeregisterStat(m_incomingPacketPoolStat);
-
- // We won't null out the pool to avoid a race condition with code that may be in the middle of using it.
-
- return true;
- }
-
- return false;
+ m_elapsedMSSinceLastStatReport = Environment.TickCount;
}
///
@@ -403,6 +311,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
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);
+ base.Stop();
+ }
+
public void AddScene(IScene scene)
{
if (m_scene != null)
@@ -419,117 +333,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_scene = (Scene)scene;
m_location = new Location(m_scene.RegionInfo.RegionHandle);
-
- MainConsole.Instance.Commands.AddCommand(
- "Debug",
- false,
- "debug lludp start",
- "debug lludp start ",
- "Control LLUDP packet processing.",
- "No effect if packet processing has already started.\n"
- + "in - start inbound processing.\n"
- + "out - start outbound processing.\n"
- + "all - start in and outbound processing.\n",
- HandleStartCommand);
-
- MainConsole.Instance.Commands.AddCommand(
- "Debug",
- false,
- "debug lludp stop",
- "debug lludp stop ",
- "Stop LLUDP packet processing.",
- "No effect if packet processing has already stopped.\n"
- + "in - stop inbound processing.\n"
- + "out - stop outbound processing.\n"
- + "all - stop in and outbound processing.\n",
- HandleStopCommand);
-
- MainConsole.Instance.Commands.AddCommand(
- "Debug",
- false,
- "debug lludp pool",
- "debug lludp pool ",
- "Turn object pooling within the lludp component on or off.",
- HandlePoolCommand);
-
- MainConsole.Instance.Commands.AddCommand(
- "Debug",
- false,
- "debug lludp status",
- "debug lludp status",
- "Return status of LLUDP packet processing.",
- HandleStatusCommand);
- }
-
- private void HandleStartCommand(string module, string[] args)
- {
- if (args.Length != 4)
- {
- MainConsole.Instance.Output("Usage: debug lludp start ");
- return;
- }
-
- string subCommand = args[3];
-
- if (subCommand == "in" || subCommand == "all")
- StartInbound();
-
- if (subCommand == "out" || subCommand == "all")
- StartOutbound();
- }
-
- private void HandleStopCommand(string module, string[] args)
- {
- if (args.Length != 4)
- {
- MainConsole.Instance.Output("Usage: debug lludp stop ");
- return;
- }
-
- string subCommand = args[3];
-
- if (subCommand == "in" || subCommand == "all")
- StopInbound();
-
- if (subCommand == "out" || subCommand == "all")
- StopOutbound();
- }
-
- private void HandlePoolCommand(string module, string[] args)
- {
- if (args.Length != 4)
- {
- MainConsole.Instance.Output("Usage: debug lludp pool ");
- return;
- }
-
- string enabled = args[3];
-
- if (enabled == "on")
- {
- if (EnablePools())
- MainConsole.Instance.OutputFormat("Packet pools enabled on {0}", m_scene.Name);
- }
- else if (enabled == "off")
- {
- if (DisablePools())
- MainConsole.Instance.OutputFormat("Packet pools disabled on {0}", m_scene.Name);
- }
- else
- {
- MainConsole.Instance.Output("Usage: debug lludp pool ");
- }
- }
-
- private void HandleStatusCommand(string module, string[] args)
- {
- MainConsole.Instance.OutputFormat(
- "IN LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningInbound ? "enabled" : "disabled");
-
- MainConsole.Instance.OutputFormat(
- "OUT LLUDP packet processing for {0} is {1}", m_scene.Name, IsRunningOutbound ? "enabled" : "disabled");
-
- MainConsole.Instance.OutputFormat("LLUDP pools in {0} are {1}", m_scene.Name, UsePools ? "on" : "off");
}
public bool HandlesRegion(Location x)
@@ -613,8 +416,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
byte[] data = packet.ToBytes();
SendPacketData(udpClient, data, packet.Type, category, method);
}
-
- PacketPool.Instance.ReturnPacket(packet);
}
///
@@ -899,7 +700,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
LLUDPClient udpClient = null;
Packet packet = null;
int packetEnd = buffer.DataLength - 1;
- IPEndPoint endPoint = (IPEndPoint)buffer.RemoteEndPoint;
+ IPEndPoint address = (IPEndPoint)buffer.RemoteEndPoint;
#region Decoding
@@ -909,7 +710,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// "[LLUDPSERVER]: Dropping undersized packet with {0} bytes received from {1} in {2}",
// buffer.DataLength, buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName);
- return; // Drop undersized packet
+ return; // Drop undersizd packet
}
int headerLen = 7;
@@ -932,13 +733,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
try
{
-// packet = Packet.BuildPacket(buffer.Data, ref packetEnd,
-// // Only allocate a buffer for zerodecoding if the packet is zerocoded
-// ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null);
- // If OpenSimUDPBase.UsePool == true (which is currently separate from the PacketPool) then we
- // assume that packet construction does not retain a reference to byte[] buffer.Data (instead, all
- // bytes are copied out).
- packet = PacketPool.Instance.GetPacket(buffer.Data, ref packetEnd,
+ packet = Packet.BuildPacket(buffer.Data, ref packetEnd,
// Only allocate a buffer for zerodecoding if the packet is zerocoded
((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null);
}
@@ -953,13 +748,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return; // Drop short packet
}
- catch (Exception e)
+ catch(Exception e)
{
if (m_malformedCount < 100)
m_log.DebugFormat("[LLUDPSERVER]: Dropped malformed packet: " + e.ToString());
-
m_malformedCount++;
-
if ((m_malformedCount % 100000) == 0)
m_log.DebugFormat("[LLUDPSERVER]: Received {0} malformed packets so far, probable network attack.", m_malformedCount);
}
@@ -979,7 +772,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// If there is already a client for this endpoint, don't process UseCircuitCode
IClientAPI client = null;
- if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView))
+ if (!m_scene.TryGetClient(address, out client))
{
// UseCircuitCode handling
if (packet.Type == PacketType.UseCircuitCode)
@@ -987,15 +780,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// And if there is a UseCircuitCode pending, also drop it
lock (m_pendingCache)
{
- if (m_pendingCache.Contains(endPoint))
+ if (m_pendingCache.Contains(address))
return;
- m_pendingCache.AddOrUpdate(endPoint, new Queue(), 60);
+ m_pendingCache.AddOrUpdate(address, new Queue(), 60);
}
- // We need to copy the endpoint so that it doesn't get changed when another thread reuses the
- // buffer.
- object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet };
+ object[] array = new object[] { buffer, packet };
Util.FireAndForget(HandleUseCircuitCode, array);
@@ -1007,7 +798,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
lock (m_pendingCache)
{
Queue queue;
- if (m_pendingCache.TryGetValue(endPoint, out queue))
+ if (m_pendingCache.TryGetValue(address, out queue))
{
//m_log.DebugFormat("[LLUDPSERVER]: Enqueued a {0} packet into the pending queue", packet.Type);
queue.Enqueue(buffer);
@@ -1043,10 +834,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Handle appended ACKs
if (packet.Header.AppendedAcks && packet.Header.AckList != null)
{
-// m_log.DebugFormat(
-// "[LLUDPSERVER]: Handling {0} appended acks from {1} in {2}",
-// packet.Header.AckList.Length, client.Name, m_scene.Name);
-
for (int i = 0; i < packet.Header.AckList.Length; i++)
udpClient.NeedAcks.Acknowledge(packet.Header.AckList[i], now, packet.Header.Resent);
}
@@ -1056,10 +843,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
PacketAckPacket ackPacket = (PacketAckPacket)packet;
-// m_log.DebugFormat(
-// "[LLUDPSERVER]: Handling {0} packet acks for {1} in {2}",
-// ackPacket.Packets.Length, client.Name, m_scene.Name);
-
for (int i = 0; i < ackPacket.Packets.Length; i++)
udpClient.NeedAcks.Acknowledge(ackPacket.Packets[i].ID, now, packet.Header.Resent);
@@ -1073,10 +856,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (packet.Header.Reliable)
{
-// m_log.DebugFormat(
-// "[LLUDPSERVER]: Adding ack request for {0} {1} from {2} in {3}",
-// packet.Type, packet.Header.Sequence, client.Name, m_scene.Name);
-
udpClient.PendingAcks.Enqueue(packet.Header.Sequence);
// This is a somewhat odd sequence of steps to pull the client.BytesSinceLastACK value out,
@@ -1123,8 +902,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (packet.Type == PacketType.StartPingCheck)
{
-// m_log.DebugFormat("[LLUDPSERVER]: Handling ping from {0} in {1}", client.Name, m_scene.Name);
-
// We don't need to do anything else with ping checks
StartPingCheckPacket startPing = (StartPingCheckPacket)packet;
CompletePing(udpClient, startPing.PingID.PingID);
@@ -1144,25 +921,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#endregion Ping Check Handling
- IncomingPacket incomingPacket;
-
// Inbox insertion
- if (UsePools)
- {
- incomingPacket = m_incomingPacketPool.GetObject();
- incomingPacket.Client = (LLClientView)client;
- incomingPacket.Packet = packet;
- }
- else
- {
- incomingPacket = new IncomingPacket((LLClientView)client, packet);
- }
-
- if (incomingPacket.Packet.Type == PacketType.AgentUpdate ||
- incomingPacket.Packet.Type == PacketType.ChatFromViewer)
- packetInbox.EnqueueHigh(incomingPacket);
+ if (packet.Type == PacketType.AgentUpdate ||
+ packet.Type == PacketType.ChatFromViewer)
+ packetInbox.EnqueueHigh(new IncomingPacket((LLClientView)client, packet));
else
- packetInbox.EnqueueLow(incomingPacket);
+ packetInbox.EnqueueLow(new IncomingPacket((LLClientView)client, packet));
+// packetInbox.Enqueue(new IncomingPacket((LLClientView)client, packet));
}
#region BinaryStats
@@ -1248,19 +1013,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private void HandleUseCircuitCode(object o)
{
- IPEndPoint endPoint = null;
+ IPEndPoint remoteEndPoint = null;
IClientAPI client = null;
try
{
// DateTime startTime = DateTime.Now;
object[] array = (object[])o;
- endPoint = (IPEndPoint)array[0];
+ UDPPacketBuffer buffer = (UDPPacketBuffer)array[0];
UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1];
m_log.DebugFormat(
"[LLUDPSERVER]: Handling UseCircuitCode request for circuit {0} to {1} from IP {2}",
- uccp.CircuitCode.Code, m_scene.RegionInfo.RegionName, endPoint);
+ uccp.CircuitCode.Code, m_scene.RegionInfo.RegionName, buffer.RemoteEndPoint);
+
+ remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;
AuthenticateResponse sessionInfo;
if (IsClientAuthorized(uccp, out sessionInfo))
@@ -1271,13 +1038,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
uccp.CircuitCode.Code,
uccp.CircuitCode.ID,
uccp.CircuitCode.SessionID,
- endPoint,
+ remoteEndPoint,
sessionInfo);
// Send ack straight away to let the viewer know that the connection is active.
// The client will be null if it already exists (e.g. if on a region crossing the client sends a use
// circuit code to the existing child agent. This is not particularly obvious.
- SendAckImmediate(endPoint, uccp.Header.Sequence);
+ SendAckImmediate(remoteEndPoint, uccp.Header.Sequence);
// We only want to send initial data to new clients, not ones which are being converted from child to root.
if (client != null)
@@ -1291,12 +1058,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
lock (m_pendingCache)
{
- if (!m_pendingCache.TryGetValue(endPoint, out queue))
+ if (!m_pendingCache.TryGetValue(remoteEndPoint, out queue))
{
m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present");
return;
}
- m_pendingCache.Remove(endPoint);
+ m_pendingCache.Remove(remoteEndPoint);
}
m_log.DebugFormat("[LLUDPSERVER]: Client created, processing pending queue, {0} entries", queue.Count);
@@ -1314,9 +1081,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Don't create clients for unauthorized requesters.
m_log.WarnFormat(
"[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}",
- uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint);
+ uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, remoteEndPoint);
lock (m_pendingCache)
- m_pendingCache.Remove(endPoint);
+ m_pendingCache.Remove(remoteEndPoint);
}
// m_log.DebugFormat(
@@ -1328,7 +1095,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
m_log.ErrorFormat(
"[LLUDPSERVER]: UseCircuitCode handling from endpoint {0}, client {1} {2} failed. Exception {3}{4}",
- endPoint != null ? endPoint.ToString() : "n/a",
+ remoteEndPoint != null ? remoteEndPoint.ToString() : "n/a",
client != null ? client.Name : "unknown",
client != null ? client.AgentId.ToString() : "unknown",
e.Message,
@@ -1393,20 +1160,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
IClientAPI client = null;
- // We currently synchronize this code across the whole scene to avoid issues such as
- // http://opensimulator.org/mantis/view.php?id=5365 However, once locking per agent circuit can be done
- // consistently, this lock could probably be removed.
- lock (this)
+ // In priciple there shouldn't be more than one thread here, ever.
+ // But in case that happens, we need to synchronize this piece of code
+ // because it's too important
+ lock (this)
{
if (!m_scene.TryGetClient(agentID, out client))
{
LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO);
-
+
client = new LLClientView(m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
client.OnLogout += LogoutHandler;
-
+
((LLClientView)client).DisableFacelights = m_disableFacelights;
-
+
client.Start();
}
}
@@ -1445,7 +1212,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// on to en-US to avoid number parsing issues
Culture.SetCurrentCulture();
- while (IsRunningInbound)
+ while (base.IsRunning)
{
m_scene.ThreadAlive(1);
try
@@ -1461,12 +1228,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
if (packetInbox.Dequeue(100, ref incomingPacket))
- {
ProcessInPacket(incomingPacket);//, incomingPacket); Util.FireAndForget(ProcessInPacket, incomingPacket);
-
- if (UsePools)
- m_incomingPacketPool.ReturnObject(incomingPacket);
- }
}
catch (Exception ex)
{
@@ -1493,7 +1255,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Action generic every round
Action clientPacketHandler = ClientOutgoingPacketHandler;
- while (base.IsRunningOutbound)
+ while (base.IsRunning)
{
m_scene.ThreadAlive(2);
try
@@ -1761,7 +1523,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (!client.IsLoggingOut)
{
client.IsLoggingOut = true;
- client.Close(false, false);
+ client.Close(false);
}
}
}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
index 8bd3461..cfe7c9d 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs
@@ -30,8 +30,6 @@ using System.Net;
using System.Net.Sockets;
using System.Threading;
using log4net;
-using OpenSim.Framework;
-using OpenSim.Framework.Monitoring;
namespace OpenMetaverse
{
@@ -60,31 +58,17 @@ namespace OpenMetaverse
/// Flag to process packets asynchronously or synchronously
private bool m_asyncPacketHandling;
- ///
- /// Pool to use for handling data. May be null if UsePools = false;
- ///
- protected OpenSim.Framework.Pool m_pool;
-
- ///
- /// Are we to use object pool(s) to reduce memory churn when receiving data?
- ///
- public bool UsePools { get; protected set; }
-
- /// Returns true if the server is currently listening for inbound packets, otherwise false
- public bool IsRunningInbound { get; private set; }
+ /// The all important shutdown flag
+ private volatile bool m_shutdownFlag = true;
- /// Returns true if the server is currently sending outbound packets, otherwise false
- /// If IsRunningOut = false, then any request to send a packet is simply dropped.
- public bool IsRunningOutbound { get; private set; }
-
- private Stat m_poolCountStat;
+ /// Returns true if the server is currently listening, otherwise false
+ public bool IsRunning { get { return !m_shutdownFlag; } }
///
/// Default constructor
///
/// Local IP address to bind the server to
/// Port to listening for incoming UDP packets on
- /// /// Are we to use an object pool to get objects for handing inbound data?
public OpenSimUDPBase(IPAddress bindAddress, int port)
{
m_localBindAddress = bindAddress;
@@ -92,7 +76,7 @@ namespace OpenMetaverse
}
///
- /// Start inbound UDP packet handling.
+ /// Start the UDP server
///
/// The size of the receive buffer for
/// the UDP socket. This value is passed up to the operating system
@@ -107,11 +91,11 @@ namespace OpenMetaverse
/// manner (not throwing an exception when the remote side resets the
/// connection). This call is ignored on Mono where the flag is not
/// necessary
- public void StartInbound(int recvBufferSize, bool asyncPacketHandling)
+ public void Start(int recvBufferSize, bool asyncPacketHandling)
{
m_asyncPacketHandling = asyncPacketHandling;
- if (!IsRunningInbound)
+ if (m_shutdownFlag)
{
const int SIO_UDP_CONNRESET = -1744830452;
@@ -139,7 +123,8 @@ namespace OpenMetaverse
m_udpSocket.Bind(ipep);
- IsRunningInbound = true;
+ // we're not shutting down, we're starting up
+ m_shutdownFlag = false;
// kick off an async receive. The Start() method will return, the
// actual receives will occur asynchronously and will be caught in
@@ -149,84 +134,28 @@ namespace OpenMetaverse
}
///
- /// Start outbound UDP packet handling.
+ /// Stops the UDP server
///
- public void StartOutbound()
- {
- IsRunningOutbound = true;
- }
-
- public void StopInbound()
+ public void Stop()
{
- if (IsRunningInbound)
+ if (!m_shutdownFlag)
{
// wait indefinitely for a writer lock. Once this is called, the .NET runtime
// will deny any more reader locks, in effect blocking all other send/receive
- // threads. Once we have the lock, we set IsRunningInbound = false to inform the other
+ // threads. Once we have the lock, we set shutdownFlag to inform the other
// threads that the socket is closed.
- IsRunningInbound = false;
+ m_shutdownFlag = true;
m_udpSocket.Close();
}
}
- public void StopOutbound()
- {
- IsRunningOutbound = false;
- }
-
- protected virtual bool EnablePools()
- {
- if (!UsePools)
- {
- m_pool = new Pool(() => new UDPPacketBuffer(), 500);
-
- m_poolCountStat
- = new Stat(
- "UDPPacketBufferPoolCount",
- "Objects within the UDPPacketBuffer pool",
- "The number of objects currently stored within the UDPPacketBuffer pool",
- "",
- "clientstack",
- "packetpool",
- StatType.Pull,
- stat => stat.Value = m_pool.Count,
- StatVerbosity.Debug);
-
- StatsManager.RegisterStat(m_poolCountStat);
-
- UsePools = true;
-
- return true;
- }
-
- return false;
- }
-
- protected virtual bool DisablePools()
- {
- if (UsePools)
- {
- UsePools = false;
- StatsManager.DeregisterStat(m_poolCountStat);
-
- // We won't null out the pool to avoid a race condition with code that may be in the middle of using it.
-
- return true;
- }
-
- return false;
- }
-
private void AsyncBeginReceive()
{
- UDPPacketBuffer buf;
-
- if (UsePools)
- buf = m_pool.GetObject();
- else
- buf = new UDPPacketBuffer();
+ // allocate a packet buffer
+ //WrappedObject wrappedBuffer = Pool.CheckOut();
+ UDPPacketBuffer buf = new UDPPacketBuffer();
- if (IsRunningInbound)
+ if (!m_shutdownFlag)
{
try
{
@@ -279,7 +208,7 @@ namespace OpenMetaverse
{
// Asynchronous receive operations will complete here through the call
// to AsyncBeginReceive
- if (IsRunningInbound)
+ if (!m_shutdownFlag)
{
// Asynchronous mode will start another receive before the
// callback for this packet is even fired. Very parallel :-)
@@ -288,6 +217,8 @@ namespace OpenMetaverse
// get the buffer that was created in AsyncBeginReceive
// this is the received data
+ //WrappedObject wrappedBuffer = (WrappedObject)iar.AsyncState;
+ //UDPPacketBuffer buffer = wrappedBuffer.Instance;
UDPPacketBuffer buffer = (UDPPacketBuffer)iar.AsyncState;
try
@@ -304,8 +235,7 @@ namespace OpenMetaverse
catch (ObjectDisposedException) { }
finally
{
- if (UsePools)
- m_pool.ReturnObject(buffer);
+ //wrappedBuffer.Dispose();
// Synchronous mode waits until the packet callback completes
// before starting the receive to fetch another packet
@@ -318,7 +248,7 @@ namespace OpenMetaverse
public void AsyncBeginSend(UDPPacketBuffer buf)
{
- if (IsRunningOutbound)
+ if (!m_shutdownFlag)
{
try
{
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs b/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
deleted file mode 100644
index 9f22fb4..0000000
--- a/OpenSim/Region/ClientStack/Linden/UDP/PacketPool.cs
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * 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.Collections.Generic;
-using System.Reflection;
-using OpenMetaverse;
-using OpenMetaverse.Packets;
-using log4net;
-using OpenSim.Framework.Monitoring;
-
-namespace OpenSim.Region.ClientStack.LindenUDP
-{
- public sealed class PacketPool
- {
- private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
-
- private static readonly PacketPool instance = new PacketPool();
-
- private bool packetPoolEnabled = true;
- private bool dataBlockPoolEnabled = true;
-
- private PercentageStat m_packetsReusedStat = new PercentageStat(
- "PacketsReused",
- "Packets reused",
- "Number of packets reused out of all requests to the packet pool",
- "clientstack",
- "packetpool",
- StatType.Push,
- null,
- StatVerbosity.Debug);
-
- private PercentageStat m_blocksReusedStat = new PercentageStat(
- "PacketDataBlocksReused",
- "Packet data blocks reused",
- "Number of data blocks reused out of all requests to the packet pool",
- "clientstack",
- "packetpool",
- StatType.Push,
- null,
- StatVerbosity.Debug);
-
- ///
- /// Pool of packets available for reuse.
- ///
- private readonly Dictionary> pool = new Dictionary>();
-
- private static Dictionary> DataBlocks = new Dictionary>();
-
- public static PacketPool Instance
- {
- get { return instance; }
- }
-
- public bool RecyclePackets
- {
- set { packetPoolEnabled = value; }
- get { return packetPoolEnabled; }
- }
-
- public bool RecycleDataBlocks
- {
- set { dataBlockPoolEnabled = value; }
- get { return dataBlockPoolEnabled; }
- }
-
- private PacketPool()
- {
- StatsManager.RegisterStat(m_packetsReusedStat);
- StatsManager.RegisterStat(m_blocksReusedStat);
-
- StatsManager.RegisterStat(
- new Stat(
- "PacketsPoolCount",
- "Objects within the packet pool",
- "The number of objects currently stored within the packet pool",
- "",
- "clientstack",
- "packetpool",
- StatType.Pull,
- stat => { lock (pool) { stat.Value = pool.Count; } },
- StatVerbosity.Debug));
-
- StatsManager.RegisterStat(
- new Stat(
- "PacketDataBlocksPoolCount",
- "Objects within the packet data block pool",
- "The number of objects currently stored within the packet data block pool",
- "",
- "clientstack",
- "packetpool",
- StatType.Pull,
- stat => { lock (DataBlocks) { stat.Value = DataBlocks.Count; } },
- StatVerbosity.Debug));
- }
-
- ///
- /// Gets a packet of the given type.
- ///
- ///
- /// Guaranteed to always return a packet, whether from the pool or newly constructed.
- public Packet GetPacket(PacketType type)
- {
- m_packetsReusedStat.Consequent++;
-
- Packet packet;
-
- if (!packetPoolEnabled)
- return Packet.BuildPacket(type);
-
- lock (pool)
- {
- if (!pool.ContainsKey(type) || pool[type] == null || (pool[type]).Count == 0)
- {
-// m_log.DebugFormat("[PACKETPOOL]: Building {0} packet", type);
-
- // Creating a new packet if we cannot reuse an old package
- packet = Packet.BuildPacket(type);
- }
- else
- {
-// m_log.DebugFormat("[PACKETPOOL]: Pulling {0} packet", type);
-
- // Recycle old packages
- m_packetsReusedStat.Antecedent++;
-
- packet = pool[type].Pop();
- }
- }
-
- return packet;
- }
-
- // private byte[] decoded_header = new byte[10];
- private static PacketType GetType(byte[] bytes)
- {
- byte[] decoded_header = new byte[10 + 8];
- ushort id;
- PacketFrequency freq;
-
- if ((bytes[0] & Helpers.MSG_ZEROCODED) != 0)
- {
- Helpers.ZeroDecode(bytes, 16, decoded_header);
- }
- else
- {
- Buffer.BlockCopy(bytes, 0, decoded_header, 0, 10);
- }
-
- if (decoded_header[6] == 0xFF)
- {
- if (decoded_header[7] == 0xFF)
- {
- id = (ushort) ((decoded_header[8] << 8) + decoded_header[9]);
- freq = PacketFrequency.Low;
- }
- else
- {
- id = decoded_header[7];
- freq = PacketFrequency.Medium;
- }
- }
- else
- {
- id = decoded_header[6];
- freq = PacketFrequency.High;
- }
-
- return Packet.GetType(id, freq);
- }
-
- public Packet GetPacket(byte[] bytes, ref int packetEnd, byte[] zeroBuffer)
- {
- PacketType type = GetType(bytes);
-
-// Array.Clear(zeroBuffer, 0, zeroBuffer.Length);
-
- int i = 0;
- Packet packet = GetPacket(type);
- if (packet == null)
- m_log.WarnFormat("[PACKETPOOL]: Failed to get packet of type {0}", type);
- else
- packet.FromBytes(bytes, ref i, ref packetEnd, zeroBuffer);
-
- return packet;
- }
-
- ///
- /// Return a packet to the packet pool
- ///
- ///
- public void ReturnPacket(Packet packet)
- {
- if (dataBlockPoolEnabled)
- {
- switch (packet.Type)
- {
- case PacketType.ObjectUpdate:
- ObjectUpdatePacket oup = (ObjectUpdatePacket)packet;
-
- foreach (ObjectUpdatePacket.ObjectDataBlock oupod in oup.ObjectData)
- ReturnDataBlock(oupod);
-
- oup.ObjectData = null;
- break;
-
- case PacketType.ImprovedTerseObjectUpdate:
- ImprovedTerseObjectUpdatePacket itoup = (ImprovedTerseObjectUpdatePacket)packet;
-
- foreach (ImprovedTerseObjectUpdatePacket.ObjectDataBlock itoupod in itoup.ObjectData)
- ReturnDataBlock(itoupod);
-
- itoup.ObjectData = null;
- break;
- }
- }
-
- if (packetPoolEnabled)
- {
- switch (packet.Type)
- {
- // List pooling packets here
- case PacketType.AgentUpdate:
- case PacketType.PacketAck:
- case PacketType.ObjectUpdate:
- case PacketType.ImprovedTerseObjectUpdate:
- lock (pool)
- {
- PacketType type = packet.Type;
-
- if (!pool.ContainsKey(type))
- {
- pool[type] = new Stack();
- }
-
- if ((pool[type]).Count < 50)
- {
-// m_log.DebugFormat("[PACKETPOOL]: Pushing {0} packet", type);
-
- pool[type].Push(packet);
- }
- }
- break;
-
- // Other packets wont pool
- default:
- return;
- }
- }
- }
-
- public T GetDataBlock() where T: new()
- {
- lock (DataBlocks)
- {
- m_blocksReusedStat.Consequent++;
-
- Stack s;
-
- if (DataBlocks.TryGetValue(typeof(T), out s))
- {
- if (s.Count > 0)
- {
- m_blocksReusedStat.Antecedent++;
- return (T)s.Pop();
- }
- }
- else
- {
- DataBlocks[typeof(T)] = new Stack();
- }
-
- return new T();
- }
- }
-
- public void ReturnDataBlock(T block) where T: new()
- {
- if (block == null)
- return;
-
- lock (DataBlocks)
- {
- if (!DataBlocks.ContainsKey(typeof(T)))
- DataBlocks[typeof(T)] = new Stack();
-
- if (DataBlocks[typeof(T)].Count < 50)
- DataBlocks[typeof(T)].Push(block);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs
index 556df30..109a8e1 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/Tests/BasicCircuitTests.cs
@@ -43,7 +43,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
/// This will contain basic tests for the LindenUDP client stack
///
[TestFixture]
- public class BasicCircuitTests : OpenSimTestCase
+ public class BasicCircuitTests
{
private Scene m_scene;
private TestLLUDPServer m_udpServer;
@@ -65,9 +65,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
}
[SetUp]
- public override void SetUp()
+ public void SetUp()
{
- base.SetUp();
m_scene = new SceneHelpers().SetupScene();
}
@@ -144,7 +143,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP.Tests
public void TestAddClient()
{
TestHelpers.InMethod();
-// TestHelpers.EnableLogging();
+// XmlConfigurator.Configure();
AddUdpServer();
--
cgit v1.1
From 5e0294815f7e3ec83b7e568e1468948ac0ff7331 Mon Sep 17 00:00:00 2001
From: teravus
Date: Sat, 17 Nov 2012 03:47:09 -0500
Subject: * Plumbing and basic setting of the GetMesh Cap Throttler. * Last
step is to flip the throttle distribution.
---
.../ClientStack/Linden/Caps/GetMeshModule.cs | 90 +++++++++++++++++-----
.../Region/ClientStack/Linden/UDP/LLClientView.cs | 12 +++
.../Region/ClientStack/Linden/UDP/LLUDPClient.cs | 4 +
3 files changed, 88 insertions(+), 18 deletions(-)
(limited to 'OpenSim/Region/ClientStack/Linden')
diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
index 8deff81..96b48ad 100644
--- a/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
+++ b/OpenSim/Region/ClientStack/Linden/Caps/GetMeshModule.cs
@@ -60,6 +60,7 @@ namespace OpenSim.Region.ClientStack.Linden
private IAssetService m_AssetService;
private bool m_Enabled = true;
private string m_URL;
+
struct aPollRequest
{
public PollServiceMeshEventArgs thepoll;
@@ -71,6 +72,7 @@ namespace OpenSim.Region.ClientStack.Linden
{
public Hashtable response;
public int bytes;
+ public int lod;
}
@@ -112,6 +114,7 @@ namespace OpenSim.Region.ClientStack.Linden
// Cap doesn't exist
if (m_URL != string.Empty)
m_Enabled = true;
+
}
public void AddRegion(Scene pScene)
@@ -192,7 +195,7 @@ namespace OpenSim.Region.ClientStack.Linden
PollServiceMeshEventArgs args;
if (m_pollservices.TryGetValue(user, out args))
{
- args.UpdateThrottle(imagethrottle);
+ args.UpdateThrottle(imagethrottle, p);
}
}
@@ -242,11 +245,12 @@ namespace OpenSim.Region.ClientStack.Linden
new Dictionary();
private Scene m_scene;
- private CapsDataThrottler m_throttler = new CapsDataThrottler(100000, 1400000, 10000);
+ private MeshCapsDataThrottler m_throttler;
public PollServiceMeshEventArgs(UUID pId, Scene scene) :
base(null, null, null, null, pId, int.MaxValue)
{
m_scene = scene;
+ m_throttler = new MeshCapsDataThrottler(100000, 1400000, 10000, scene);
// x is request id, y is userid
HasEvents = (x, y) =>
{
@@ -268,6 +272,7 @@ namespace OpenSim.Region.ClientStack.Linden
}
finally
{
+ m_throttler.ProcessTime();
responses.Remove(x);
}
}
@@ -323,7 +328,7 @@ namespace OpenSim.Region.ClientStack.Linden
response["reusecontext"] = false;
lock (responses)
- responses[requestID] = new aPollResponse() { bytes = 0, response = response };
+ responses[requestID] = new aPollResponse() { bytes = 0, response = response, lod = 0 };
return;
}
@@ -334,6 +339,7 @@ namespace OpenSim.Region.ClientStack.Linden
responses[requestID] = new aPollResponse()
{
bytes = (int)response["int_bytes"],
+ lod = (int)response["int_lod"],
response = response
};
@@ -341,9 +347,9 @@ namespace OpenSim.Region.ClientStack.Linden
m_throttler.ProcessTime();
}
- internal void UpdateThrottle(int pimagethrottle)
+ internal void UpdateThrottle(int pimagethrottle, ScenePresence p)
{
- m_throttler.ThrottleBytes = pimagethrottle;
+ m_throttler.UpdateThrottle(pimagethrottle, p);
}
}
@@ -398,18 +404,31 @@ namespace OpenSim.Region.ClientStack.Linden
}
}
- internal sealed class CapsDataThrottler
+ internal sealed class MeshCapsDataThrottler
{
private volatile int currenttime = 0;
private volatile int lastTimeElapsed = 0;
private volatile int BytesSent = 0;
- private int oversizedImages = 0;
- public CapsDataThrottler(int pBytes, int max, int min)
+ private int Lod3 = 0;
+ private int Lod2 = 0;
+ private int Lod1 = 0;
+ private int UserSetThrottle = 0;
+ private int UDPSetThrottle = 0;
+ private int CapSetThrottle = 0;
+ private float CapThrottleDistributon = 0.30f;
+ private readonly Scene m_scene;
+ private ThrottleOutPacketType Throttle;
+
+ public MeshCapsDataThrottler(int pBytes, int max, int min, Scene pScene)
{
ThrottleBytes = pBytes;
lastTimeElapsed = Util.EnvironmentTickCount();
+ Throttle = ThrottleOutPacketType.Task;
+ m_scene = pScene;
}
+
+
public bool hasEvents(UUID key, Dictionary responses)
{
PassTime();
@@ -427,17 +446,23 @@ namespace OpenSim.Region.ClientStack.Linden
if (BytesSent + response.bytes <= ThrottleBytes)
{
BytesSent += response.bytes;
- //TimeBasedAction timeBasedAction = new TimeBasedAction { byteRemoval = response.bytes, requestId = key, timeMS = currenttime + 1000, unlockyn = false };
- //m_actions.Add(timeBasedAction);
+
+ return true;
+ }
+ // Lod3 Over
+ else if (response.bytes > ThrottleBytes && Lod3 <= (((ThrottleBytes * .30f) % 50000) + 1))
+ {
+ Interlocked.Increment(ref Lod3);
+ BytesSent += response.bytes;
+
return true;
}
- // Big textures
- else if (response.bytes > ThrottleBytes && oversizedImages <= ((ThrottleBytes % 50000) + 1))
+ // Lod2 Over
+ else if (response.bytes > ThrottleBytes && Lod2 <= (((ThrottleBytes * .30f) % 10000) + 1))
{
- Interlocked.Increment(ref oversizedImages);
+ Interlocked.Increment(ref Lod2);
BytesSent += response.bytes;
- //TimeBasedAction timeBasedAction = new TimeBasedAction { byteRemoval = response.bytes, requestId = key, timeMS = currenttime + (((response.bytes % ThrottleBytes)+1)*1000) , unlockyn = false };
- //m_actions.Add(timeBasedAction);
+
return true;
}
else
@@ -448,6 +473,11 @@ namespace OpenSim.Region.ClientStack.Linden
return haskey;
}
+ public void SubtractBytes(int bytes,int lod)
+ {
+ BytesSent -= bytes;
+ }
+
public void ProcessTime()
{
PassTime();
@@ -459,18 +489,42 @@ namespace OpenSim.Region.ClientStack.Linden
currenttime = Util.EnvironmentTickCount();
int timeElapsed = Util.EnvironmentTickCountSubtract(currenttime, lastTimeElapsed);
//processTimeBasedActions(responses);
- if (Util.EnvironmentTickCountSubtract(currenttime, timeElapsed) >= 1000)
+ if (currenttime - timeElapsed >= 1000)
{
lastTimeElapsed = Util.EnvironmentTickCount();
BytesSent -= ThrottleBytes;
if (BytesSent < 0) BytesSent = 0;
if (BytesSent < ThrottleBytes)
{
- oversizedImages = 0;
+ Lod3 = 0;
+ Lod2 = 0;
+ Lod1 = 0;
}
}
}
- public int ThrottleBytes;
+ private void AlterThrottle(int setting, ScenePresence p)
+ {
+ p.ControllingClient.SetAgentThrottleSilent((int)Throttle,setting);
+ }
+
+ public int ThrottleBytes
+ {
+ get { return CapSetThrottle; }
+ set { CapSetThrottle = value; }
+ }
+
+ internal void UpdateThrottle(int pimagethrottle, ScenePresence p)
+ {
+ // Client set throttle !
+ UserSetThrottle = pimagethrottle;
+ CapSetThrottle = (int)(pimagethrottle*CapThrottleDistributon);
+ UDPSetThrottle = (int) (pimagethrottle*(100 - CapThrottleDistributon));
+ if (CapSetThrottle < 4068)
+ CapSetThrottle = 4068; // at least two discovery mesh
+ p.ControllingClient.SetAgentThrottleSilent((int) Throttle, UDPSetThrottle);
+ ProcessTime();
+
+ }
}
}
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index ae9ed7f..533a1a8 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -11884,6 +11884,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
///
+ /// Sets the throttles from values supplied by the client
+ ///
+ ///
+ public void SetAgentThrottleSilent(int throttle, int setting)
+ {
+ m_udpClient.ForceThrottleSetting(throttle,setting);
+ //m_udpClient.SetThrottles(throttles);
+
+ }
+
+
+ ///
/// Get the current throttles for this client as a packed byte array
///
/// Unused
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index c472176..f675377 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
@@ -682,6 +682,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (m_nextOnQueueEmpty == 0)
m_nextOnQueueEmpty = 1;
}
+ internal void ForceThrottleSetting(int throttle, int setting)
+ {
+ m_throttleCategories[throttle].RequestedDripRate = Math.Max(setting, LLUDPServer.MTU); ;
+ }
///
/// Converts a integer to a
--
cgit v1.1