diff options
author | Melanie | 2012-10-17 00:03:02 +0100 |
---|---|---|
committer | Melanie | 2012-10-17 00:03:02 +0100 |
commit | ad60a29c9303e68717ccc057988a36da0990b0ae (patch) | |
tree | a4e965250d291476b1449bd0e949e5e204cf0446 | |
parent | Merge branch 'master' into careminster (diff) | |
parent | Add optional pool for the UDPPacketBuffer objects that handle all incoming UD... (diff) | |
download | opensim-SC-ad60a29c9303e68717ccc057988a36da0990b0ae.zip opensim-SC-ad60a29c9303e68717ccc057988a36da0990b0ae.tar.gz opensim-SC-ad60a29c9303e68717ccc057988a36da0990b0ae.tar.bz2 opensim-SC-ad60a29c9303e68717ccc057988a36da0990b0ae.tar.xz |
Merge branch 'master' into careminster
Conflicts:
OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Framework/Pool.cs | 76 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | 54 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs | 31 | ||||
-rw-r--r-- | bin/OpenSimDefaults.ini | 6 |
4 files changed, 136 insertions, 31 deletions
diff --git a/OpenSim/Framework/Pool.cs b/OpenSim/Framework/Pool.cs new file mode 100644 index 0000000..1ca06c3 --- /dev/null +++ b/OpenSim/Framework/Pool.cs | |||
@@ -0,0 +1,76 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | |||
31 | namespace OpenSim.Framework | ||
32 | { | ||
33 | /// <summary> | ||
34 | /// Naive pool implementation. | ||
35 | /// </summary> | ||
36 | /// <remarks> | ||
37 | /// Currently assumes that objects are in a useable state when returned. | ||
38 | /// </remarks> | ||
39 | public class Pool<T> | ||
40 | { | ||
41 | private Stack<T> m_pool; | ||
42 | |||
43 | private int m_maxPoolSize; | ||
44 | |||
45 | private Func<T> m_createFunction; | ||
46 | |||
47 | public Pool(Func<T> createFunction, int maxSize) | ||
48 | { | ||
49 | m_maxPoolSize = maxSize; | ||
50 | m_createFunction = createFunction; | ||
51 | m_pool = new Stack<T>(m_maxPoolSize); | ||
52 | } | ||
53 | |||
54 | public T GetObject() | ||
55 | { | ||
56 | lock (m_pool) | ||
57 | { | ||
58 | if (m_pool.Count > 0) | ||
59 | return m_pool.Pop(); | ||
60 | else | ||
61 | return m_createFunction(); | ||
62 | } | ||
63 | } | ||
64 | |||
65 | public void ReturnObject(T obj) | ||
66 | { | ||
67 | lock (m_pool) | ||
68 | { | ||
69 | if (m_pool.Count >= m_maxPoolSize) | ||
70 | return; | ||
71 | else | ||
72 | m_pool.Push(obj); | ||
73 | } | ||
74 | } | ||
75 | } | ||
76 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs index 1d304db..7820caf 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs | |||
@@ -192,7 +192,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
192 | /// </summary> | 192 | /// </summary> |
193 | private IClientAPI m_currentIncomingClient; | 193 | private IClientAPI m_currentIncomingClient; |
194 | 194 | ||
195 | public LLUDPServer(IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource, AgentCircuitManager circuitManager) | 195 | public LLUDPServer( |
196 | IPAddress listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, | ||
197 | IConfigSource configSource, AgentCircuitManager circuitManager) | ||
196 | : base(listenIP, (int)port) | 198 | : base(listenIP, (int)port) |
197 | { | 199 | { |
198 | #region Environment.TickCount Measurement | 200 | #region Environment.TickCount Measurement |
@@ -246,6 +248,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
246 | { | 248 | { |
247 | PacketPool.Instance.RecyclePackets = packetConfig.GetBoolean("RecyclePackets", true); | 249 | PacketPool.Instance.RecyclePackets = packetConfig.GetBoolean("RecyclePackets", true); |
248 | PacketPool.Instance.RecycleDataBlocks = packetConfig.GetBoolean("RecycleDataBlocks", true); | 250 | PacketPool.Instance.RecycleDataBlocks = packetConfig.GetBoolean("RecycleDataBlocks", true); |
251 | UsePools = packetConfig.GetBoolean("RecycleBaseUDPPackets", false); | ||
249 | } | 252 | } |
250 | 253 | ||
251 | #region BinaryStats | 254 | #region BinaryStats |
@@ -288,8 +291,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
288 | private void StartInbound() | 291 | private void StartInbound() |
289 | { | 292 | { |
290 | m_log.InfoFormat( | 293 | m_log.InfoFormat( |
291 | "[LLUDPSERVER]: Starting inbound packet processing for the LLUDP server in {0} mode", | 294 | "[LLUDPSERVER]: Starting inbound packet processing for the LLUDP server in {0} mode with UsePools = {1}", |
292 | m_asyncPacketHandling ? "asynchronous" : "synchronous"); | 295 | m_asyncPacketHandling ? "asynchronous" : "synchronous", UsePools); |
293 | 296 | ||
294 | base.StartInbound(m_recvBufferSize, m_asyncPacketHandling); | 297 | base.StartInbound(m_recvBufferSize, m_asyncPacketHandling); |
295 | 298 | ||
@@ -304,7 +307,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
304 | Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS); | 307 | Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS); |
305 | } | 308 | } |
306 | 309 | ||
307 | private void StartOutbound() | 310 | private new void StartOutbound() |
308 | { | 311 | { |
309 | m_log.Info("[LLUDPSERVER]: Starting outbound packet processing for the LLUDP server"); | 312 | m_log.Info("[LLUDPSERVER]: Starting outbound packet processing for the LLUDP server"); |
310 | 313 | ||
@@ -321,7 +324,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
321 | Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS); | 324 | Watchdog.DEFAULT_WATCHDOG_TIMEOUT_MS); |
322 | } | 325 | } |
323 | 326 | ||
324 | public new void Stop() | 327 | public void Stop() |
325 | { | 328 | { |
326 | m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName); | 329 | m_log.Info("[LLUDPSERVER]: Shutting down the LLUDP server for " + m_scene.RegionInfo.RegionName); |
327 | base.StopOutbound(); | 330 | base.StopOutbound(); |
@@ -810,7 +813,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
810 | LLUDPClient udpClient = null; | 813 | LLUDPClient udpClient = null; |
811 | Packet packet = null; | 814 | Packet packet = null; |
812 | int packetEnd = buffer.DataLength - 1; | 815 | int packetEnd = buffer.DataLength - 1; |
813 | IPEndPoint address = (IPEndPoint)buffer.RemoteEndPoint; | 816 | IPEndPoint endPoint = (IPEndPoint)buffer.RemoteEndPoint; |
814 | 817 | ||
815 | #region Decoding | 818 | #region Decoding |
816 | 819 | ||
@@ -820,7 +823,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
820 | // "[LLUDPSERVER]: Dropping undersized packet with {0} bytes received from {1} in {2}", | 823 | // "[LLUDPSERVER]: Dropping undersized packet with {0} bytes received from {1} in {2}", |
821 | // buffer.DataLength, buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName); | 824 | // buffer.DataLength, buffer.RemoteEndPoint, m_scene.RegionInfo.RegionName); |
822 | 825 | ||
823 | return; // Drop undersizd packet | 826 | return; // Drop undersized packet |
824 | } | 827 | } |
825 | 828 | ||
826 | int headerLen = 7; | 829 | int headerLen = 7; |
@@ -846,6 +849,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
846 | // packet = Packet.BuildPacket(buffer.Data, ref packetEnd, | 849 | // packet = Packet.BuildPacket(buffer.Data, ref packetEnd, |
847 | // // Only allocate a buffer for zerodecoding if the packet is zerocoded | 850 | // // Only allocate a buffer for zerodecoding if the packet is zerocoded |
848 | // ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null); | 851 | // ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null); |
852 | // If OpenSimUDPBase.UsePool == true (which is currently separate from the PacketPool) then we | ||
853 | // assume that packet construction does not retain a reference to byte[] buffer.Data (instead, all | ||
854 | // bytes are copied out). | ||
849 | packet = PacketPool.Instance.GetPacket(buffer.Data, ref packetEnd, | 855 | packet = PacketPool.Instance.GetPacket(buffer.Data, ref packetEnd, |
850 | // Only allocate a buffer for zerodecoding if the packet is zerocoded | 856 | // Only allocate a buffer for zerodecoding if the packet is zerocoded |
851 | ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null); | 857 | ((buffer.Data[0] & Helpers.MSG_ZEROCODED) != 0) ? new byte[4096] : null); |
@@ -887,7 +893,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
887 | 893 | ||
888 | // If there is already a client for this endpoint, don't process UseCircuitCode | 894 | // If there is already a client for this endpoint, don't process UseCircuitCode |
889 | IClientAPI client = null; | 895 | IClientAPI client = null; |
890 | if (!m_scene.TryGetClient(address, out client)) | 896 | if (!m_scene.TryGetClient(endPoint, out client) || !(client is LLClientView)) |
891 | { | 897 | { |
892 | // UseCircuitCode handling | 898 | // UseCircuitCode handling |
893 | if (packet.Type == PacketType.UseCircuitCode) | 899 | if (packet.Type == PacketType.UseCircuitCode) |
@@ -895,13 +901,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
895 | // And if there is a UseCircuitCode pending, also drop it | 901 | // And if there is a UseCircuitCode pending, also drop it |
896 | lock (m_pendingCache) | 902 | lock (m_pendingCache) |
897 | { | 903 | { |
898 | if (m_pendingCache.Contains(address)) | 904 | if (m_pendingCache.Contains(endPoint)) |
899 | return; | 905 | return; |
900 | 906 | ||
901 | m_pendingCache.AddOrUpdate(address, new Queue<UDPPacketBuffer>(), 60); | 907 | m_pendingCache.AddOrUpdate(endPoint, new Queue<UDPPacketBuffer>(), 60); |
902 | } | 908 | } |
903 | 909 | ||
904 | object[] array = new object[] { buffer, packet }; | 910 | // We need to copy the endpoint so that it doesn't get changed when another thread reuses the |
911 | // buffer. | ||
912 | object[] array = new object[] { new IPEndPoint(endPoint.Address, endPoint.Port), packet }; | ||
905 | 913 | ||
906 | Util.FireAndForget(HandleUseCircuitCode, array); | 914 | Util.FireAndForget(HandleUseCircuitCode, array); |
907 | 915 | ||
@@ -913,7 +921,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
913 | lock (m_pendingCache) | 921 | lock (m_pendingCache) |
914 | { | 922 | { |
915 | Queue<UDPPacketBuffer> queue; | 923 | Queue<UDPPacketBuffer> queue; |
916 | if (m_pendingCache.TryGetValue(address, out queue)) | 924 | if (m_pendingCache.TryGetValue(endPoint, out queue)) |
917 | { | 925 | { |
918 | //m_log.DebugFormat("[LLUDPSERVER]: Enqueued a {0} packet into the pending queue", packet.Type); | 926 | //m_log.DebugFormat("[LLUDPSERVER]: Enqueued a {0} packet into the pending queue", packet.Type); |
919 | queue.Enqueue(buffer); | 927 | queue.Enqueue(buffer); |
@@ -1128,21 +1136,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1128 | 1136 | ||
1129 | private void HandleUseCircuitCode(object o) | 1137 | private void HandleUseCircuitCode(object o) |
1130 | { | 1138 | { |
1131 | IPEndPoint remoteEndPoint = null; | 1139 | IPEndPoint endPoint = null; |
1132 | IClientAPI client = null; | 1140 | IClientAPI client = null; |
1133 | 1141 | ||
1134 | try | 1142 | try |
1135 | { | 1143 | { |
1136 | // DateTime startTime = DateTime.Now; | 1144 | // DateTime startTime = DateTime.Now; |
1137 | object[] array = (object[])o; | 1145 | object[] array = (object[])o; |
1138 | UDPPacketBuffer buffer = (UDPPacketBuffer)array[0]; | 1146 | endPoint = (IPEndPoint)array[0]; |
1139 | UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1]; | 1147 | UseCircuitCodePacket uccp = (UseCircuitCodePacket)array[1]; |
1140 | 1148 | ||
1141 | m_log.DebugFormat( | 1149 | m_log.DebugFormat( |
1142 | "[LLUDPSERVER]: Handling UseCircuitCode request for circuit {0} to {1} from IP {2}", | 1150 | "[LLUDPSERVER]: Handling UseCircuitCode request for circuit {0} to {1} from IP {2}", |
1143 | uccp.CircuitCode.Code, m_scene.RegionInfo.RegionName, buffer.RemoteEndPoint); | 1151 | uccp.CircuitCode.Code, m_scene.RegionInfo.RegionName, endPoint); |
1144 | |||
1145 | remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint; | ||
1146 | 1152 | ||
1147 | AuthenticateResponse sessionInfo; | 1153 | AuthenticateResponse sessionInfo; |
1148 | if (IsClientAuthorized(uccp, out sessionInfo)) | 1154 | if (IsClientAuthorized(uccp, out sessionInfo)) |
@@ -1153,13 +1159,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1153 | uccp.CircuitCode.Code, | 1159 | uccp.CircuitCode.Code, |
1154 | uccp.CircuitCode.ID, | 1160 | uccp.CircuitCode.ID, |
1155 | uccp.CircuitCode.SessionID, | 1161 | uccp.CircuitCode.SessionID, |
1156 | remoteEndPoint, | 1162 | endPoint, |
1157 | sessionInfo); | 1163 | sessionInfo); |
1158 | 1164 | ||
1159 | // Send ack straight away to let the viewer know that the connection is active. | 1165 | // Send ack straight away to let the viewer know that the connection is active. |
1160 | // The client will be null if it already exists (e.g. if on a region crossing the client sends a use | 1166 | // The client will be null if it already exists (e.g. if on a region crossing the client sends a use |
1161 | // circuit code to the existing child agent. This is not particularly obvious. | 1167 | // circuit code to the existing child agent. This is not particularly obvious. |
1162 | SendAckImmediate(remoteEndPoint, uccp.Header.Sequence); | 1168 | SendAckImmediate(endPoint, uccp.Header.Sequence); |
1163 | 1169 | ||
1164 | // We only want to send initial data to new clients, not ones which are being converted from child to root. | 1170 | // We only want to send initial data to new clients, not ones which are being converted from child to root. |
1165 | if (client != null) | 1171 | if (client != null) |
@@ -1173,12 +1179,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1173 | 1179 | ||
1174 | lock (m_pendingCache) | 1180 | lock (m_pendingCache) |
1175 | { | 1181 | { |
1176 | if (!m_pendingCache.TryGetValue(remoteEndPoint, out queue)) | 1182 | if (!m_pendingCache.TryGetValue(endPoint, out queue)) |
1177 | { | 1183 | { |
1178 | m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present"); | 1184 | m_log.DebugFormat("[LLUDPSERVER]: Client created but no pending queue present"); |
1179 | return; | 1185 | return; |
1180 | } | 1186 | } |
1181 | m_pendingCache.Remove(remoteEndPoint); | 1187 | m_pendingCache.Remove(endPoint); |
1182 | } | 1188 | } |
1183 | 1189 | ||
1184 | m_log.DebugFormat("[LLUDPSERVER]: Client created, processing pending queue, {0} entries", queue.Count); | 1190 | m_log.DebugFormat("[LLUDPSERVER]: Client created, processing pending queue, {0} entries", queue.Count); |
@@ -1196,9 +1202,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1196 | // Don't create clients for unauthorized requesters. | 1202 | // Don't create clients for unauthorized requesters. |
1197 | m_log.WarnFormat( | 1203 | m_log.WarnFormat( |
1198 | "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", | 1204 | "[LLUDPSERVER]: Ignoring connection request for {0} to {1} with unknown circuit code {2} from IP {3}", |
1199 | uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, remoteEndPoint); | 1205 | uccp.CircuitCode.ID, m_scene.RegionInfo.RegionName, uccp.CircuitCode.Code, endPoint); |
1200 | lock (m_pendingCache) | 1206 | lock (m_pendingCache) |
1201 | m_pendingCache.Remove(remoteEndPoint); | 1207 | m_pendingCache.Remove(endPoint); |
1202 | } | 1208 | } |
1203 | 1209 | ||
1204 | // m_log.DebugFormat( | 1210 | // m_log.DebugFormat( |
@@ -1210,7 +1216,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1210 | { | 1216 | { |
1211 | m_log.ErrorFormat( | 1217 | m_log.ErrorFormat( |
1212 | "[LLUDPSERVER]: UseCircuitCode handling from endpoint {0}, client {1} {2} failed. Exception {3}{4}", | 1218 | "[LLUDPSERVER]: UseCircuitCode handling from endpoint {0}, client {1} {2} failed. Exception {3}{4}", |
1213 | remoteEndPoint != null ? remoteEndPoint.ToString() : "n/a", | 1219 | endPoint != null ? endPoint.ToString() : "n/a", |
1214 | client != null ? client.Name : "unknown", | 1220 | client != null ? client.Name : "unknown", |
1215 | client != null ? client.AgentId.ToString() : "unknown", | 1221 | client != null ? client.AgentId.ToString() : "unknown", |
1216 | e.Message, | 1222 | e.Message, |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs index 82775fd..e7d8a30 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/OpenSimUDPBase.cs | |||
@@ -30,6 +30,7 @@ using System.Net; | |||
30 | using System.Net.Sockets; | 30 | using System.Net.Sockets; |
31 | using System.Threading; | 31 | using System.Threading; |
32 | using log4net; | 32 | using log4net; |
33 | using OpenSim.Framework; | ||
33 | 34 | ||
34 | namespace OpenMetaverse | 35 | namespace OpenMetaverse |
35 | { | 36 | { |
@@ -58,6 +59,16 @@ namespace OpenMetaverse | |||
58 | /// <summary>Flag to process packets asynchronously or synchronously</summary> | 59 | /// <summary>Flag to process packets asynchronously or synchronously</summary> |
59 | private bool m_asyncPacketHandling; | 60 | private bool m_asyncPacketHandling; |
60 | 61 | ||
62 | /// <summary> | ||
63 | /// Pool to use for handling data. May be null if UsePools = false; | ||
64 | /// </summary> | ||
65 | protected OpenSim.Framework.Pool<UDPPacketBuffer> m_pool; | ||
66 | |||
67 | /// <summary> | ||
68 | /// Are we to use object pool(s) to reduce memory churn when receiving data? | ||
69 | /// </summary> | ||
70 | public bool UsePools { get; protected set; } | ||
71 | |||
61 | /// <summary>Returns true if the server is currently listening for inbound packets, otherwise false</summary> | 72 | /// <summary>Returns true if the server is currently listening for inbound packets, otherwise false</summary> |
62 | public bool IsRunningInbound { get; private set; } | 73 | public bool IsRunningInbound { get; private set; } |
63 | 74 | ||
@@ -70,6 +81,7 @@ namespace OpenMetaverse | |||
70 | /// </summary> | 81 | /// </summary> |
71 | /// <param name="bindAddress">Local IP address to bind the server to</param> | 82 | /// <param name="bindAddress">Local IP address to bind the server to</param> |
72 | /// <param name="port">Port to listening for incoming UDP packets on</param> | 83 | /// <param name="port">Port to listening for incoming UDP packets on</param> |
84 | /// /// <param name="usePool">Are we to use an object pool to get objects for handing inbound data?</param> | ||
73 | public OpenSimUDPBase(IPAddress bindAddress, int port) | 85 | public OpenSimUDPBase(IPAddress bindAddress, int port) |
74 | { | 86 | { |
75 | m_localBindAddress = bindAddress; | 87 | m_localBindAddress = bindAddress; |
@@ -94,6 +106,11 @@ namespace OpenMetaverse | |||
94 | /// necessary</remarks> | 106 | /// necessary</remarks> |
95 | public void StartInbound(int recvBufferSize, bool asyncPacketHandling) | 107 | public void StartInbound(int recvBufferSize, bool asyncPacketHandling) |
96 | { | 108 | { |
109 | if (UsePools) | ||
110 | m_pool = new Pool<UDPPacketBuffer>(() => new UDPPacketBuffer(), 500); | ||
111 | else | ||
112 | m_pool = null; | ||
113 | |||
97 | m_asyncPacketHandling = asyncPacketHandling; | 114 | m_asyncPacketHandling = asyncPacketHandling; |
98 | 115 | ||
99 | if (!IsRunningInbound) | 116 | if (!IsRunningInbound) |
@@ -161,9 +178,12 @@ namespace OpenMetaverse | |||
161 | 178 | ||
162 | private void AsyncBeginReceive() | 179 | private void AsyncBeginReceive() |
163 | { | 180 | { |
164 | // allocate a packet buffer | 181 | UDPPacketBuffer buf; |
165 | //WrappedObject<UDPPacketBuffer> wrappedBuffer = Pool.CheckOut(); | 182 | |
166 | UDPPacketBuffer buf = new UDPPacketBuffer(); | 183 | if (UsePools) |
184 | buf = m_pool.GetObject(); | ||
185 | else | ||
186 | buf = new UDPPacketBuffer(); | ||
167 | 187 | ||
168 | if (IsRunningInbound) | 188 | if (IsRunningInbound) |
169 | { | 189 | { |
@@ -227,8 +247,6 @@ namespace OpenMetaverse | |||
227 | 247 | ||
228 | // get the buffer that was created in AsyncBeginReceive | 248 | // get the buffer that was created in AsyncBeginReceive |
229 | // this is the received data | 249 | // this is the received data |
230 | //WrappedObject<UDPPacketBuffer> wrappedBuffer = (WrappedObject<UDPPacketBuffer>)iar.AsyncState; | ||
231 | //UDPPacketBuffer buffer = wrappedBuffer.Instance; | ||
232 | UDPPacketBuffer buffer = (UDPPacketBuffer)iar.AsyncState; | 250 | UDPPacketBuffer buffer = (UDPPacketBuffer)iar.AsyncState; |
233 | 251 | ||
234 | try | 252 | try |
@@ -245,7 +263,8 @@ namespace OpenMetaverse | |||
245 | catch (ObjectDisposedException) { } | 263 | catch (ObjectDisposedException) { } |
246 | finally | 264 | finally |
247 | { | 265 | { |
248 | //wrappedBuffer.Dispose(); | 266 | if (UsePools) |
267 | m_pool.ReturnObject(buffer); | ||
249 | 268 | ||
250 | // Synchronous mode waits until the packet callback completes | 269 | // Synchronous mode waits until the packet callback completes |
251 | // before starting the receive to fetch another packet | 270 | // before starting the receive to fetch another packet |
diff --git a/bin/OpenSimDefaults.ini b/bin/OpenSimDefaults.ini index 6a67e77..7d321a7 100644 --- a/bin/OpenSimDefaults.ini +++ b/bin/OpenSimDefaults.ini | |||
@@ -1598,10 +1598,14 @@ | |||
1598 | 1598 | ||
1599 | 1599 | ||
1600 | [PacketPool] | 1600 | [PacketPool] |
1601 | ; Enables the experimental packet pool. Yes, we've been here before. | ||
1602 | ;RecyclePackets = true; | 1601 | ;RecyclePackets = true; |
1603 | ;RecycleDataBlocks = true; | 1602 | ;RecycleDataBlocks = true; |
1604 | 1603 | ||
1604 | ; If true, then the basic packet objects used to receive data are also recycled, not just the LLUDP packets. | ||
1605 | ; This reduces data churn | ||
1606 | ; This setting is currently experimental and defaults to false. | ||
1607 | RecycleBaseUDPPackets = false; | ||
1608 | |||
1605 | 1609 | ||
1606 | [InterestManagement] | 1610 | [InterestManagement] |
1607 | ; This section controls how state updates are prioritized for each client | 1611 | ; This section controls how state updates are prioritized for each client |