aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework
diff options
context:
space:
mode:
authorAdam Johnson2007-12-28 08:51:39 +0000
committerAdam Johnson2007-12-28 08:51:39 +0000
commit79496381fc68cbd30ff5a95d1f05fcb18c6b1a93 (patch)
tree036414391293354da62fe9eac1895483111480a3 /OpenSim/Framework
parent* Moved PrimitiveBaseShape subclasses into factory methods - the subclassing ... (diff)
downloadopensim-SC-79496381fc68cbd30ff5a95d1f05fcb18c6b1a93.zip
opensim-SC-79496381fc68cbd30ff5a95d1f05fcb18c6b1a93.tar.gz
opensim-SC-79496381fc68cbd30ff5a95d1f05fcb18c6b1a93.tar.bz2
opensim-SC-79496381fc68cbd30ff5a95d1f05fcb18c6b1a93.tar.xz
Patch from Johan: LibSL updated to the latest revision (1568) and all packets are now
recycled to improve performance and memory usage.
Diffstat (limited to 'OpenSim/Framework')
-rw-r--r--OpenSim/Framework/ClientManager.cs26
-rw-r--r--OpenSim/Framework/PacketPool.cs131
2 files changed, 144 insertions, 13 deletions
diff --git a/OpenSim/Framework/ClientManager.cs b/OpenSim/Framework/ClientManager.cs
index da60ed7..181000c 100644
--- a/OpenSim/Framework/ClientManager.cs
+++ b/OpenSim/Framework/ClientManager.cs
@@ -26,11 +26,9 @@
26* 26*
27*/ 27*/
28 28
29using System;
30using System.Collections.Generic; 29using System.Collections.Generic;
31using libsecondlife; 30using libsecondlife;
32using libsecondlife.Packets; 31using libsecondlife.Packets;
33using OpenSim.Framework.Console;
34 32
35namespace OpenSim.Framework 33namespace OpenSim.Framework
36{ 34{
@@ -42,6 +40,7 @@ namespace OpenSim.Framework
42 40
43 public void ForEachClient(ForEachClientDelegate whatToDo) 41 public void ForEachClient(ForEachClientDelegate whatToDo)
44 { 42 {
43
45 // Wasteful, I know 44 // Wasteful, I know
46 IClientAPI[] LocalClients = new IClientAPI[0]; 45 IClientAPI[] LocalClients = new IClientAPI[0];
47 lock (m_clients) 46 lock (m_clients)
@@ -56,11 +55,9 @@ namespace OpenSim.Framework
56 { 55 {
57 whatToDo(LocalClients[i]); 56 whatToDo(LocalClients[i]);
58 } 57 }
59 catch (Exception e) 58 catch (System.Exception e)
60 { 59 {
61 MainLog.Instance.Warn("CLIENT", 60 OpenSim.Framework.Console.MainLog.Instance.Warn("CLIENT", "Unable to do ForEachClient for one of the clients" + "\n Reason: " + e.ToString());
62 "Unable to do ForEachClient for one of the clients" + "\n Reason: " +
63 e.ToString());
64 } 61 }
65 } 62 }
66 } 63 }
@@ -110,19 +107,20 @@ namespace OpenSim.Framework
110 IClientAPI client; 107 IClientAPI client;
111 try 108 try
112 { 109 {
110
113 if (m_clients.TryGetValue(circuits[i], out client)) 111 if (m_clients.TryGetValue(circuits[i], out client))
114 { 112 {
115 Remove(client.CircuitCode); 113 Remove(client.CircuitCode);
116 client.Close(false); 114 client.Close(false);
117 } 115 }
118 } 116 }
119 catch (Exception e) 117 catch (System.Exception e)
120 { 118 {
121 MainLog.Instance.Error("CLIENT", 119 OpenSim.Framework.Console.MainLog.Instance.Error("CLIENT", "Unable to shutdown circuit for: " + agentId.ToString() + "\n Reason: " + e.ToString());
122 "Unable to shutdown circuit for: " + agentId.ToString() + "\n Reason: " +
123 e.ToString());
124 } 120 }
125 } 121 }
122
123
126 } 124 }
127 125
128 private uint[] GetAllCircuits(LLUUID agentId) 126 private uint[] GetAllCircuits(LLUUID agentId)
@@ -137,7 +135,7 @@ namespace OpenSim.Framework
137 } 135 }
138 136
139 137
140 for (int i = 0; i < LocalClients.Length; i++) 138 for (int i = 0; i < LocalClients.Length; i++ )
141 { 139 {
142 if (LocalClients[i].AgentId == agentId) 140 if (LocalClients[i].AgentId == agentId)
143 { 141 {
@@ -150,7 +148,8 @@ namespace OpenSim.Framework
150 148
151 public void ViewerEffectHandler(IClientAPI sender, ViewerEffectPacket.EffectBlock[] effectBlock) 149 public void ViewerEffectHandler(IClientAPI sender, ViewerEffectPacket.EffectBlock[] effectBlock)
152 { 150 {
153 ViewerEffectPacket packet = new ViewerEffectPacket(); 151 ViewerEffectPacket packet = (ViewerEffectPacket) PacketPool.Instance.GetPacket(PacketType.ViewerEffect);
152 // TODO: don't create new blocks if recycling an old packet
154 packet.Effect = effectBlock; 153 packet.Effect = effectBlock;
155 154
156 // Wasteful, I know 155 // Wasteful, I know
@@ -170,6 +169,7 @@ namespace OpenSim.Framework
170 packet.AgentData.SessionID = LocalClients[i].SessionId; 169 packet.AgentData.SessionID = LocalClients[i].SessionId;
171 LocalClients[i].OutPacket(packet, ThrottleOutPacketType.Task); 170 LocalClients[i].OutPacket(packet, ThrottleOutPacketType.Task);
172 } 171 }
172
173 } 173 }
174 } 174 }
175 175
@@ -178,4 +178,4 @@ namespace OpenSim.Framework
178 return m_clients.TryGetValue(circuitId, out user); 178 return m_clients.TryGetValue(circuitId, out user);
179 } 179 }
180 } 180 }
181} \ No newline at end of file 181}
diff --git a/OpenSim/Framework/PacketPool.cs b/OpenSim/Framework/PacketPool.cs
new file mode 100644
index 0000000..2b33d0b
--- /dev/null
+++ b/OpenSim/Framework/PacketPool.cs
@@ -0,0 +1,131 @@
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 OpenSim 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*/
28using System;
29using System.Collections;
30using libsecondlife.Packets;
31
32namespace OpenSim.Framework
33{
34 public sealed class PacketPool
35 {
36 // Set up a thread-safe singleton pattern
37 static PacketPool()
38 {
39 }
40
41 private static readonly PacketPool instance = new PacketPool();
42
43 public static PacketPool Instance
44 {
45 get { return instance; }
46 }
47
48 private Hashtable pool = new Hashtable();
49
50 public Packet GetPacket(PacketType type)
51 {
52 Packet packet = null;
53
54 lock (pool)
55 {
56 if (pool[type] == null || ((Stack) pool[type]).Count == 0)
57 {
58 // Creating a new packet if we cannot reuse an old package
59 packet = Packet.BuildPacket(type);
60 }
61 else
62 {
63 // Recycle old packages
64 packet = (Packet) ((Stack) pool[type]).Pop();
65 }
66 }
67
68 return packet;
69 }
70
71 private byte[] decoded_header = new byte[10];
72 private PacketType GetType(byte[] bytes)
73 {
74 ushort id;
75 libsecondlife.PacketFrequency freq;
76
77 Buffer.BlockCopy(bytes, 0, decoded_header, 0, 10);
78
79 if((bytes[0] & libsecondlife.Helpers.MSG_ZEROCODED)!=0)
80 {
81 libsecondlife.Helpers.ZeroDecodeCommand(bytes, decoded_header);
82 }
83
84 if (decoded_header[6] == 0xFF)
85 {
86 if (decoded_header[7] == 0xFF)
87 {
88 id = (ushort)((decoded_header[8] << 8) + decoded_header[9]);
89 freq = libsecondlife.PacketFrequency.Low;
90 }
91 else
92 {
93 id = (ushort)decoded_header[7];
94 freq = libsecondlife.PacketFrequency.Medium;
95 }
96 }
97 else
98 {
99 id = (ushort)decoded_header[6];
100 freq = libsecondlife.PacketFrequency.High;
101 }
102
103 return Packet.GetType(id, freq);
104 }
105
106 public Packet GetPacket(byte[] bytes, ref int packetEnd, byte[] zeroBuffer)
107 {
108 PacketType type = GetType(bytes);
109
110 int i = 0;
111 Packet packet = GetPacket(type);
112 packet.FromBytes(bytes, ref i, ref packetEnd, zeroBuffer);
113 return packet;
114 }
115
116 public void ReturnPacket(Packet packet)
117 {
118 lock (pool)
119 {
120 PacketType type = packet.Type;
121
122 if (pool[type] == null)
123 {
124 pool[type] = new Stack();
125 }
126
127 ((Stack) pool[type]).Push(packet);
128 }
129 }
130 }
131}