diff options
Diffstat (limited to 'OpenSim/Framework')
-rw-r--r-- | OpenSim/Framework/Communications/Services/LoginService.cs | 18 | ||||
-rw-r--r-- | OpenSim/Framework/IClientAPI.cs | 2 | ||||
-rw-r--r-- | OpenSim/Framework/RegionInfo.cs | 305 | ||||
-rw-r--r-- | OpenSim/Framework/Servers/VersionInfo.cs | 3 | ||||
-rw-r--r-- | OpenSim/Framework/TaskInventoryDictionary.cs | 117 | ||||
-rw-r--r-- | OpenSim/Framework/Util.cs | 26 |
6 files changed, 439 insertions, 32 deletions
diff --git a/OpenSim/Framework/Communications/Services/LoginService.cs b/OpenSim/Framework/Communications/Services/LoginService.cs index 71b38ed..824cc57 100644 --- a/OpenSim/Framework/Communications/Services/LoginService.cs +++ b/OpenSim/Framework/Communications/Services/LoginService.cs | |||
@@ -88,15 +88,7 @@ namespace OpenSim.Framework.Communications.Services | |||
88 | m_welcomeMessage = welcomeMess; | 88 | m_welcomeMessage = welcomeMess; |
89 | } | 89 | } |
90 | } | 90 | } |
91 | 91 | ||
92 | /// <summary> | ||
93 | /// If the user is already logged in, try to notify the region that the user they've got is dead. | ||
94 | /// </summary> | ||
95 | /// <param name="theUser"></param> | ||
96 | public virtual void LogOffUser(UserProfileData theUser, string message) | ||
97 | { | ||
98 | } | ||
99 | |||
100 | /// <summary> | 92 | /// <summary> |
101 | /// Called when we receive the client's initial XMLRPC login_to_simulator request message | 93 | /// Called when we receive the client's initial XMLRPC login_to_simulator request message |
102 | /// </summary> | 94 | /// </summary> |
@@ -1056,7 +1048,13 @@ namespace OpenSim.Framework.Communications.Services | |||
1056 | 1048 | ||
1057 | protected abstract RegionInfo RequestClosestRegion(string region); | 1049 | protected abstract RegionInfo RequestClosestRegion(string region); |
1058 | protected abstract RegionInfo GetRegionInfo(ulong homeRegionHandle); | 1050 | protected abstract RegionInfo GetRegionInfo(ulong homeRegionHandle); |
1059 | protected abstract RegionInfo GetRegionInfo(UUID homeRegionId); | 1051 | protected abstract RegionInfo GetRegionInfo(UUID homeRegionId); |
1052 | |||
1053 | /// <summary> | ||
1054 | /// If the user is already logged in, try to notify the region that the user they've got is dead. | ||
1055 | /// </summary> | ||
1056 | /// <param name="theUser"></param> | ||
1057 | public abstract void LogOffUser(UserProfileData theUser, string message); | ||
1060 | 1058 | ||
1061 | /// <summary> | 1059 | /// <summary> |
1062 | /// Prepare a login to the given region. This involves both telling the region to expect a connection | 1060 | /// Prepare a login to the given region. This involves both telling the region to expect a connection |
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 222bae0..06c5094 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs | |||
@@ -1142,7 +1142,7 @@ namespace OpenSim.Framework | |||
1142 | 1142 | ||
1143 | void SendInstantMessage(GridInstantMessage im); | 1143 | void SendInstantMessage(GridInstantMessage im); |
1144 | 1144 | ||
1145 | void SendGenericMessage(string method, List<string> message); | 1145 | void SendGenericMessage(string method, List<byte[]> message); |
1146 | 1146 | ||
1147 | void SendLayerData(float[] map); | 1147 | void SendLayerData(float[] map); |
1148 | void SendLayerData(int px, int py, float[] map); | 1148 | void SendLayerData(int px, int py, float[] map); |
diff --git a/OpenSim/Framework/RegionInfo.cs b/OpenSim/Framework/RegionInfo.cs index baef32a..99edd99 100644 --- a/OpenSim/Framework/RegionInfo.cs +++ b/OpenSim/Framework/RegionInfo.cs | |||
@@ -36,8 +36,295 @@ using OpenMetaverse; | |||
36 | using OpenMetaverse.StructuredData; | 36 | using OpenMetaverse.StructuredData; |
37 | using OpenSim.Framework.Console; | 37 | using OpenSim.Framework.Console; |
38 | 38 | ||
39 | |||
39 | namespace OpenSim.Framework | 40 | namespace OpenSim.Framework |
40 | { | 41 | { |
42 | public class RegionMeta7WindlightData : ICloneable | ||
43 | { | ||
44 | public UUID regionID = UUID.Zero; | ||
45 | public Vector3 waterColor = new Vector3(4.0f,38.0f,64.0f); | ||
46 | public float waterFogDensityExponent = 4.0f; | ||
47 | public float underwaterFogModifier = 0.25f; | ||
48 | public Vector3 reflectionWaveletScale = new Vector3(2.0f,2.0f,2.0f); | ||
49 | public float fresnelScale = 0.40f; | ||
50 | public float fresnelOffset = 0.50f; | ||
51 | public float refractScaleAbove = 0.03f; | ||
52 | public float refractScaleBelow = 0.20f; | ||
53 | public float blurMultiplier = 0.040f; | ||
54 | public Vector2 bigWaveDirection = new Vector2(1.05f,-0.42f); | ||
55 | public Vector2 littleWaveDirection = new Vector2(1.11f,-1.16f); | ||
56 | public UUID normalMapTexture = new UUID("822ded49-9a6c-f61c-cb89-6df54f42cdf4"); | ||
57 | public Vector4 horizon = new Vector4(0.25f, 0.25f, 0.32f, 0.32f); | ||
58 | public float hazeHorizon = 0.19f; | ||
59 | public Vector4 blueDensity = new Vector4(0.12f, 0.22f, 0.38f, 0.38f); | ||
60 | public float hazeDensity = 0.70f; | ||
61 | public float densityMultiplier = 0.18f; | ||
62 | public float distanceMultiplier = 0.8f; | ||
63 | public UInt16 maxAltitude = 1605; | ||
64 | public Vector4 sunMoonColor = new Vector4(0.24f, 0.26f, 0.30f, 0.30f); | ||
65 | public float sunMoonPosition = 0.317f; | ||
66 | public Vector4 ambient = new Vector4(0.35f,0.35f,0.35f,0.35f); | ||
67 | public float eastAngle = 0.0f; | ||
68 | public float sunGlowFocus = 0.10f; | ||
69 | public float sunGlowSize = 1.75f; | ||
70 | public float sceneGamma = 1.0f; | ||
71 | public float starBrightness = 0.0f; | ||
72 | public Vector4 cloudColor = new Vector4(0.41f, 0.41f, 0.41f, 0.41f); | ||
73 | public Vector3 cloudXYDensity = new Vector3(1.00f, 0.53f, 1.00f); | ||
74 | public float cloudCoverage = 0.27f; | ||
75 | public float cloudScale = 0.42f; | ||
76 | public Vector3 cloudDetailXYDensity = new Vector3(1.00f, 0.53f, 0.12f); | ||
77 | public float cloudScrollX = 0.20f; | ||
78 | public bool cloudScrollXLock = false; | ||
79 | public float cloudScrollY = 0.01f; | ||
80 | public bool cloudScrollYLock = false; | ||
81 | public bool drawClassicClouds = true; | ||
82 | |||
83 | public delegate void SaveDelegate(RegionMeta7WindlightData wl); | ||
84 | public event SaveDelegate OnSave; | ||
85 | public void Save() | ||
86 | { | ||
87 | if (OnSave != null) | ||
88 | OnSave(this); | ||
89 | } | ||
90 | public object Clone() | ||
91 | { | ||
92 | return this.MemberwiseClone(); // call clone method | ||
93 | } | ||
94 | |||
95 | } | ||
96 | |||
97 | [Serializable] | ||
98 | public class SimpleRegionInfo | ||
99 | { | ||
100 | // private static readonly log4net.ILog m_log | ||
101 | // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | ||
102 | |||
103 | /// <summary> | ||
104 | /// The port by which http communication occurs with the region (most noticeably, CAPS communication) | ||
105 | /// </summary> | ||
106 | public uint HttpPort | ||
107 | { | ||
108 | get { return m_httpPort; } | ||
109 | set { m_httpPort = value; } | ||
110 | } | ||
111 | protected uint m_httpPort; | ||
112 | |||
113 | /// <summary> | ||
114 | /// A well-formed URI for the host region server (namely "http://" + ExternalHostName) | ||
115 | /// </summary> | ||
116 | public string ServerURI | ||
117 | { | ||
118 | get { return m_serverURI; } | ||
119 | set { m_serverURI = value; } | ||
120 | } | ||
121 | protected string m_serverURI; | ||
122 | |||
123 | public string RegionName | ||
124 | { | ||
125 | get { return m_regionName; } | ||
126 | set { m_regionName = value; } | ||
127 | } | ||
128 | protected string m_regionName = String.Empty; | ||
129 | |||
130 | protected bool Allow_Alternate_Ports; | ||
131 | public bool m_allow_alternate_ports; | ||
132 | protected string m_externalHostName; | ||
133 | |||
134 | protected IPEndPoint m_internalEndPoint; | ||
135 | protected uint? m_regionLocX; | ||
136 | protected uint? m_regionLocY; | ||
137 | protected uint m_remotingPort; | ||
138 | public UUID RegionID = UUID.Zero; | ||
139 | public string RemotingAddress; | ||
140 | public UUID ScopeID = UUID.Zero; | ||
141 | |||
142 | public SimpleRegionInfo() | ||
143 | { | ||
144 | } | ||
145 | |||
146 | public SimpleRegionInfo(uint regionLocX, uint regionLocY, IPEndPoint internalEndPoint, string externalUri) | ||
147 | { | ||
148 | m_regionLocX = regionLocX; | ||
149 | m_regionLocY = regionLocY; | ||
150 | |||
151 | m_internalEndPoint = internalEndPoint; | ||
152 | m_externalHostName = externalUri; | ||
153 | } | ||
154 | |||
155 | public SimpleRegionInfo(uint regionLocX, uint regionLocY, string externalUri, uint port) | ||
156 | { | ||
157 | m_regionLocX = regionLocX; | ||
158 | m_regionLocY = regionLocY; | ||
159 | |||
160 | m_externalHostName = externalUri; | ||
161 | |||
162 | m_internalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), (int) port); | ||
163 | } | ||
164 | |||
165 | public SimpleRegionInfo(RegionInfo ConvertFrom) | ||
166 | { | ||
167 | m_regionName = ConvertFrom.RegionName; | ||
168 | m_regionLocX = ConvertFrom.RegionLocX; | ||
169 | m_regionLocY = ConvertFrom.RegionLocY; | ||
170 | m_internalEndPoint = ConvertFrom.InternalEndPoint; | ||
171 | m_externalHostName = ConvertFrom.ExternalHostName; | ||
172 | m_remotingPort = ConvertFrom.RemotingPort; | ||
173 | m_httpPort = ConvertFrom.HttpPort; | ||
174 | m_allow_alternate_ports = ConvertFrom.m_allow_alternate_ports; | ||
175 | RemotingAddress = ConvertFrom.RemotingAddress; | ||
176 | RegionID = UUID.Zero; | ||
177 | ServerURI = ConvertFrom.ServerURI; | ||
178 | } | ||
179 | |||
180 | public uint RemotingPort | ||
181 | { | ||
182 | get { return m_remotingPort; } | ||
183 | set { m_remotingPort = value; } | ||
184 | } | ||
185 | |||
186 | /// <value> | ||
187 | /// This accessor can throw all the exceptions that Dns.GetHostAddresses can throw. | ||
188 | /// | ||
189 | /// XXX Isn't this really doing too much to be a simple getter, rather than an explict method? | ||
190 | /// </value> | ||
191 | public IPEndPoint ExternalEndPoint | ||
192 | { | ||
193 | get | ||
194 | { | ||
195 | // Old one defaults to IPv6 | ||
196 | //return new IPEndPoint(Dns.GetHostAddresses(m_externalHostName)[0], m_internalEndPoint.Port); | ||
197 | |||
198 | IPAddress ia = null; | ||
199 | // If it is already an IP, don't resolve it - just return directly | ||
200 | if (IPAddress.TryParse(m_externalHostName, out ia)) | ||
201 | return new IPEndPoint(ia, m_internalEndPoint.Port); | ||
202 | |||
203 | // Reset for next check | ||
204 | ia = null; | ||
205 | try | ||
206 | { | ||
207 | foreach (IPAddress Adr in Dns.GetHostAddresses(m_externalHostName)) | ||
208 | { | ||
209 | if (ia == null) | ||
210 | ia = Adr; | ||
211 | |||
212 | if (Adr.AddressFamily == AddressFamily.InterNetwork) | ||
213 | { | ||
214 | ia = Adr; | ||
215 | break; | ||
216 | } | ||
217 | } | ||
218 | } | ||
219 | catch (SocketException e) | ||
220 | { | ||
221 | throw new Exception( | ||
222 | "Unable to resolve local hostname " + m_externalHostName + " innerException of type '" + | ||
223 | e + "' attached to this exception", e); | ||
224 | } | ||
225 | |||
226 | return new IPEndPoint(ia, m_internalEndPoint.Port); | ||
227 | } | ||
228 | |||
229 | set { m_externalHostName = value.ToString(); } | ||
230 | } | ||
231 | |||
232 | public string ExternalHostName | ||
233 | { | ||
234 | get { return m_externalHostName; } | ||
235 | set { m_externalHostName = value; } | ||
236 | } | ||
237 | |||
238 | public IPEndPoint InternalEndPoint | ||
239 | { | ||
240 | get { return m_internalEndPoint; } | ||
241 | set { m_internalEndPoint = value; } | ||
242 | } | ||
243 | |||
244 | public uint RegionLocX | ||
245 | { | ||
246 | get { return m_regionLocX.Value; } | ||
247 | set { m_regionLocX = value; } | ||
248 | } | ||
249 | |||
250 | public uint RegionLocY | ||
251 | { | ||
252 | get { return m_regionLocY.Value; } | ||
253 | set { m_regionLocY = value; } | ||
254 | } | ||
255 | |||
256 | public ulong RegionHandle | ||
257 | { | ||
258 | get { return Util.UIntsToLong((RegionLocX * (uint) Constants.RegionSize), (RegionLocY * (uint) Constants.RegionSize)); } | ||
259 | } | ||
260 | |||
261 | public int getInternalEndPointPort() | ||
262 | { | ||
263 | return m_internalEndPoint.Port; | ||
264 | } | ||
265 | |||
266 | public Dictionary<string, object> ToKeyValuePairs() | ||
267 | { | ||
268 | Dictionary<string, object> kvp = new Dictionary<string, object>(); | ||
269 | kvp["uuid"] = RegionID.ToString(); | ||
270 | kvp["locX"] = RegionLocX.ToString(); | ||
271 | kvp["locY"] = RegionLocY.ToString(); | ||
272 | kvp["external_ip_address"] = ExternalEndPoint.Address.ToString(); | ||
273 | kvp["external_port"] = ExternalEndPoint.Port.ToString(); | ||
274 | kvp["external_host_name"] = ExternalHostName; | ||
275 | kvp["http_port"] = HttpPort.ToString(); | ||
276 | kvp["internal_ip_address"] = InternalEndPoint.Address.ToString(); | ||
277 | kvp["internal_port"] = InternalEndPoint.Port.ToString(); | ||
278 | kvp["alternate_ports"] = m_allow_alternate_ports.ToString(); | ||
279 | kvp["server_uri"] = ServerURI; | ||
280 | |||
281 | return kvp; | ||
282 | } | ||
283 | |||
284 | public SimpleRegionInfo(Dictionary<string, object> kvp) | ||
285 | { | ||
286 | if ((kvp["external_ip_address"] != null) && (kvp["external_port"] != null)) | ||
287 | { | ||
288 | int port = 0; | ||
289 | Int32.TryParse((string)kvp["external_port"], out port); | ||
290 | IPEndPoint ep = new IPEndPoint(IPAddress.Parse((string)kvp["external_ip_address"]), port); | ||
291 | ExternalEndPoint = ep; | ||
292 | } | ||
293 | else | ||
294 | ExternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0); | ||
295 | |||
296 | if (kvp["external_host_name"] != null) | ||
297 | ExternalHostName = (string)kvp["external_host_name"]; | ||
298 | |||
299 | if (kvp["http_port"] != null) | ||
300 | { | ||
301 | UInt32 port = 0; | ||
302 | UInt32.TryParse((string)kvp["http_port"], out port); | ||
303 | HttpPort = port; | ||
304 | } | ||
305 | |||
306 | if ((kvp["internal_ip_address"] != null) && (kvp["internal_port"] != null)) | ||
307 | { | ||
308 | int port = 0; | ||
309 | Int32.TryParse((string)kvp["internal_port"], out port); | ||
310 | IPEndPoint ep = new IPEndPoint(IPAddress.Parse((string)kvp["internal_ip_address"]), port); | ||
311 | InternalEndPoint = ep; | ||
312 | } | ||
313 | else | ||
314 | InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0); | ||
315 | |||
316 | if (kvp["alternate_ports"] != null) | ||
317 | { | ||
318 | bool alts = false; | ||
319 | Boolean.TryParse((string)kvp["alternate_ports"], out alts); | ||
320 | m_allow_alternate_ports = alts; | ||
321 | } | ||
322 | |||
323 | if (kvp["server_uri"] != null) | ||
324 | ServerURI = (string)kvp["server_uri"]; | ||
325 | } | ||
326 | } | ||
327 | |||
41 | public class RegionInfo | 328 | public class RegionInfo |
42 | { | 329 | { |
43 | // private static readonly log4net.ILog m_log | 330 | // private static readonly log4net.ILog m_log |
@@ -73,6 +360,7 @@ namespace OpenSim.Framework | |||
73 | private bool m_clampPrimSize = false; | 360 | private bool m_clampPrimSize = false; |
74 | private int m_objectCapacity = 0; | 361 | private int m_objectCapacity = 0; |
75 | private string m_regionType = String.Empty; | 362 | private string m_regionType = String.Empty; |
363 | private RegionMeta7WindlightData m_windlight = new RegionMeta7WindlightData(); | ||
76 | protected uint m_httpPort; | 364 | protected uint m_httpPort; |
77 | protected string m_serverURI; | 365 | protected string m_serverURI; |
78 | protected string m_regionName = String.Empty; | 366 | protected string m_regionName = String.Empty; |
@@ -211,6 +499,21 @@ namespace OpenSim.Framework | |||
211 | set { m_regionSettings = value; } | 499 | set { m_regionSettings = value; } |
212 | } | 500 | } |
213 | 501 | ||
502 | public RegionMeta7WindlightData WindlightSettings | ||
503 | { | ||
504 | get | ||
505 | { | ||
506 | if (m_windlight == null) | ||
507 | { | ||
508 | m_windlight = new RegionMeta7WindlightData(); | ||
509 | } | ||
510 | |||
511 | return m_windlight; | ||
512 | } | ||
513 | |||
514 | set { m_windlight = value; } | ||
515 | } | ||
516 | |||
214 | public int NonphysPrimMax | 517 | public int NonphysPrimMax |
215 | { | 518 | { |
216 | get { return m_nonphysPrimMax; } | 519 | get { return m_nonphysPrimMax; } |
diff --git a/OpenSim/Framework/Servers/VersionInfo.cs b/OpenSim/Framework/Servers/VersionInfo.cs index ec94b2d..f618047 100644 --- a/OpenSim/Framework/Servers/VersionInfo.cs +++ b/OpenSim/Framework/Servers/VersionInfo.cs | |||
@@ -29,9 +29,8 @@ namespace OpenSim | |||
29 | { | 29 | { |
30 | public class VersionInfo | 30 | public class VersionInfo |
31 | { | 31 | { |
32 | private const string VERSION_NUMBER = "0.6.9"; | 32 | private const string VERSION_NUMBER = "0.6.8CM"; |
33 | private const Flavour VERSION_FLAVOUR = Flavour.Dev; | 33 | private const Flavour VERSION_FLAVOUR = Flavour.Dev; |
34 | |||
35 | public enum Flavour | 34 | public enum Flavour |
36 | { | 35 | { |
37 | Unknown, | 36 | Unknown, |
diff --git a/OpenSim/Framework/TaskInventoryDictionary.cs b/OpenSim/Framework/TaskInventoryDictionary.cs index 25ae6b0..4b9a509 100644 --- a/OpenSim/Framework/TaskInventoryDictionary.cs +++ b/OpenSim/Framework/TaskInventoryDictionary.cs | |||
@@ -27,9 +27,12 @@ | |||
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Threading; | ||
31 | using System.Reflection; | ||
30 | using System.Xml; | 32 | using System.Xml; |
31 | using System.Xml.Schema; | 33 | using System.Xml.Schema; |
32 | using System.Xml.Serialization; | 34 | using System.Xml.Serialization; |
35 | using log4net; | ||
33 | using OpenMetaverse; | 36 | using OpenMetaverse; |
34 | 37 | ||
35 | namespace OpenSim.Framework | 38 | namespace OpenSim.Framework |
@@ -45,6 +48,111 @@ namespace OpenSim.Framework | |||
45 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 48 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
46 | 49 | ||
47 | private static XmlSerializer tiiSerializer = new XmlSerializer(typeof (TaskInventoryItem)); | 50 | private static XmlSerializer tiiSerializer = new XmlSerializer(typeof (TaskInventoryItem)); |
51 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
52 | |||
53 | private Thread LockedByThread; | ||
54 | /// <value> | ||
55 | /// An advanced lock for inventory data | ||
56 | /// </value> | ||
57 | private System.Threading.ReaderWriterLockSlim m_itemLock = new System.Threading.ReaderWriterLockSlim(); | ||
58 | |||
59 | /// <summary> | ||
60 | /// Are we readlocked by the calling thread? | ||
61 | /// </summary> | ||
62 | public bool IsReadLockedByMe() | ||
63 | { | ||
64 | if (m_itemLock.RecursiveReadCount > 0) | ||
65 | { | ||
66 | return true; | ||
67 | } | ||
68 | else | ||
69 | { | ||
70 | return false; | ||
71 | } | ||
72 | } | ||
73 | |||
74 | /// <summary> | ||
75 | /// Lock our inventory list for reading (many can read, one can write) | ||
76 | /// </summary> | ||
77 | public void LockItemsForRead(bool locked) | ||
78 | { | ||
79 | if (locked) | ||
80 | { | ||
81 | if (m_itemLock.IsWriteLockHeld && LockedByThread != null) | ||
82 | { | ||
83 | if (!LockedByThread.IsAlive) | ||
84 | { | ||
85 | //Locked by dead thread, reset. | ||
86 | m_itemLock = new System.Threading.ReaderWriterLockSlim(); | ||
87 | } | ||
88 | } | ||
89 | |||
90 | if (m_itemLock.RecursiveReadCount > 0) | ||
91 | { | ||
92 | m_log.Error("[TaskInventoryDictionary] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue."); | ||
93 | m_itemLock.ExitReadLock(); | ||
94 | } | ||
95 | if (m_itemLock.RecursiveWriteCount > 0) | ||
96 | { | ||
97 | m_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed."); | ||
98 | m_itemLock.ExitWriteLock(); | ||
99 | } | ||
100 | |||
101 | while (!m_itemLock.TryEnterReadLock(60000)) | ||
102 | { | ||
103 | m_log.Error("Thread lock detected while trying to aquire READ lock in TaskInventoryDictionary. Locked by thread " + LockedByThread.Name + ". I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed."); | ||
104 | if (m_itemLock.IsWriteLockHeld) | ||
105 | { | ||
106 | m_itemLock = new System.Threading.ReaderWriterLockSlim(); | ||
107 | } | ||
108 | } | ||
109 | } | ||
110 | else | ||
111 | { | ||
112 | if (m_itemLock.RecursiveReadCount>0) | ||
113 | { | ||
114 | m_itemLock.ExitReadLock(); | ||
115 | } | ||
116 | } | ||
117 | } | ||
118 | |||
119 | /// <summary> | ||
120 | /// Lock our inventory list for writing (many can read, one can write) | ||
121 | /// </summary> | ||
122 | public void LockItemsForWrite(bool locked) | ||
123 | { | ||
124 | if (locked) | ||
125 | { | ||
126 | //Enter a write lock, wait indefinately for one to open. | ||
127 | if (m_itemLock.RecursiveReadCount > 0) | ||
128 | { | ||
129 | m_log.Error("[TaskInventoryDictionary] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue."); | ||
130 | m_itemLock.ExitReadLock(); | ||
131 | } | ||
132 | if (m_itemLock.RecursiveWriteCount > 0) | ||
133 | { | ||
134 | m_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed."); | ||
135 | m_itemLock.ExitWriteLock(); | ||
136 | } | ||
137 | while (!m_itemLock.TryEnterWriteLock(60000)) | ||
138 | { | ||
139 | m_log.Error("Thread lock detected while trying to aquire WRITE lock in TaskInventoryDictionary. Locked by thread " + LockedByThread.Name + ". I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed."); | ||
140 | if (m_itemLock.IsWriteLockHeld) | ||
141 | { | ||
142 | m_itemLock = new System.Threading.ReaderWriterLockSlim(); | ||
143 | } | ||
144 | } | ||
145 | |||
146 | LockedByThread = Thread.CurrentThread; | ||
147 | } | ||
148 | else | ||
149 | { | ||
150 | if (m_itemLock.RecursiveWriteCount > 0) | ||
151 | { | ||
152 | m_itemLock.ExitWriteLock(); | ||
153 | } | ||
154 | } | ||
155 | } | ||
48 | 156 | ||
49 | #region ICloneable Members | 157 | #region ICloneable Members |
50 | 158 | ||
@@ -52,13 +160,12 @@ namespace OpenSim.Framework | |||
52 | { | 160 | { |
53 | TaskInventoryDictionary clone = new TaskInventoryDictionary(); | 161 | TaskInventoryDictionary clone = new TaskInventoryDictionary(); |
54 | 162 | ||
55 | lock (this) | 163 | m_itemLock.EnterReadLock(); |
164 | foreach (UUID uuid in Keys) | ||
56 | { | 165 | { |
57 | foreach (UUID uuid in Keys) | 166 | clone.Add(uuid, (TaskInventoryItem) this[uuid].Clone()); |
58 | { | ||
59 | clone.Add(uuid, (TaskInventoryItem) this[uuid].Clone()); | ||
60 | } | ||
61 | } | 167 | } |
168 | m_itemLock.ExitReadLock(); | ||
62 | 169 | ||
63 | return clone; | 170 | return clone; |
64 | } | 171 | } |
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 48435cb..e20b322 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs | |||
@@ -996,19 +996,19 @@ namespace OpenSim.Framework | |||
996 | { | 996 | { |
997 | string os = String.Empty; | 997 | string os = String.Empty; |
998 | 998 | ||
999 | if (Environment.OSVersion.Platform != PlatformID.Unix) | 999 | // if (Environment.OSVersion.Platform != PlatformID.Unix) |
1000 | { | 1000 | // { |
1001 | os = Environment.OSVersion.ToString(); | 1001 | // os = Environment.OSVersion.ToString(); |
1002 | } | 1002 | // } |
1003 | else | 1003 | // else |
1004 | { | 1004 | // { |
1005 | os = ReadEtcIssue(); | 1005 | // os = ReadEtcIssue(); |
1006 | } | 1006 | // } |
1007 | 1007 | // | |
1008 | if (os.Length > 45) | 1008 | // if (os.Length > 45) |
1009 | { | 1009 | // { |
1010 | os = os.Substring(0, 45); | 1010 | // os = os.Substring(0, 45); |
1011 | } | 1011 | // } |
1012 | 1012 | ||
1013 | return os; | 1013 | return os; |
1014 | } | 1014 | } |