aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorSean Dague2008-02-19 19:16:21 +0000
committerSean Dague2008-02-19 19:16:21 +0000
commit530cc2488461a4ef68a06eaba42698fcdc09f459 (patch)
treed2db34a2dcdb10b3b85aaeb200334ee9a27cae91
parentAdded to OpenSim.ini.example: (diff)
downloadopensim-SC-530cc2488461a4ef68a06eaba42698fcdc09f459.zip
opensim-SC-530cc2488461a4ef68a06eaba42698fcdc09f459.tar.gz
opensim-SC-530cc2488461a4ef68a06eaba42698fcdc09f459.tar.bz2
opensim-SC-530cc2488461a4ef68a06eaba42698fcdc09f459.tar.xz
From: Michael Osias <mosias@us.ibm.com>
This patch implements the llSendRemoteData command and fixes mantis 552, and possibly 586.
-rw-r--r--OpenSim/Region/Environment/Interfaces/IHttpRequests.cs2
-rw-r--r--OpenSim/Region/Environment/Interfaces/IWorldComm.cs5
-rw-r--r--OpenSim/Region/Environment/Interfaces/IXMLRPC.cs13
-rw-r--r--OpenSim/Region/Environment/Modules/ScriptsHttpRequests.cs31
-rw-r--r--OpenSim/Region/Environment/Modules/WorldCommModule.cs72
-rw-r--r--OpenSim/Region/Environment/Modules/XMLRPCModule.cs482
-rw-r--r--OpenSim/Region/ScriptEngine/Common/LSL_BaseClass.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs104
-rw-r--r--OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs56
10 files changed, 576 insertions, 197 deletions
diff --git a/OpenSim/Region/Environment/Interfaces/IHttpRequests.cs b/OpenSim/Region/Environment/Interfaces/IHttpRequests.cs
index 6aa8f35..946abef 100644
--- a/OpenSim/Region/Environment/Interfaces/IHttpRequests.cs
+++ b/OpenSim/Region/Environment/Interfaces/IHttpRequests.cs
@@ -38,5 +38,7 @@ namespace OpenSim.Region.Environment.Interfaces
38 LLUUID StartHttpRequest(uint localID, LLUUID itemID, string url, List<string> parameters, string body); 38 LLUUID StartHttpRequest(uint localID, LLUUID itemID, string url, List<string> parameters, string body);
39 void StopHttpRequest(uint m_localID, LLUUID m_itemID); 39 void StopHttpRequest(uint m_localID, LLUUID m_itemID);
40 HttpRequestClass GetNextCompletedRequest(); 40 HttpRequestClass GetNextCompletedRequest();
41 void RemoveCompletedRequest(LLUUID id);
42
41 } 43 }
42} \ No newline at end of file 44} \ No newline at end of file
diff --git a/OpenSim/Region/Environment/Interfaces/IWorldComm.cs b/OpenSim/Region/Environment/Interfaces/IWorldComm.cs
index 7567bb2..89c3d6f 100644
--- a/OpenSim/Region/Environment/Interfaces/IWorldComm.cs
+++ b/OpenSim/Region/Environment/Interfaces/IWorldComm.cs
@@ -41,5 +41,8 @@ namespace OpenSim.Region.Environment.Interfaces
41 void ListenControl(int handle, int active); 41 void ListenControl(int handle, int active);
42 void ListenRemove(int handle); 42 void ListenRemove(int handle);
43 void DeleteListener(LLUUID itemID); 43 void DeleteListener(LLUUID itemID);
44 uint PeekNextMessageLocalID();
45 LLUUID PeekNextMessageItemID();
46
44 } 47 }
45} \ No newline at end of file 48}
diff --git a/OpenSim/Region/Environment/Interfaces/IXMLRPC.cs b/OpenSim/Region/Environment/Interfaces/IXMLRPC.cs
index 82b692d..4d22df5 100644
--- a/OpenSim/Region/Environment/Interfaces/IXMLRPC.cs
+++ b/OpenSim/Region/Environment/Interfaces/IXMLRPC.cs
@@ -28,6 +28,8 @@
28 28
29using libsecondlife; 29using libsecondlife;
30using OpenSim.Region.Environment.Modules; 30using OpenSim.Region.Environment.Modules;
31using System.Collections;
32using System.Collections.Generic;
31 33
32namespace OpenSim.Region.Environment.Interfaces 34namespace OpenSim.Region.Environment.Interfaces
33{ 35{
@@ -36,9 +38,14 @@ namespace OpenSim.Region.Environment.Interfaces
36 LLUUID OpenXMLRPCChannel(uint localID, LLUUID itemID); 38 LLUUID OpenXMLRPCChannel(uint localID, LLUUID itemID);
37 void CloseXMLRPCChannel(LLUUID channelKey); 39 void CloseXMLRPCChannel(LLUUID channelKey);
38 bool hasRequests(); 40 bool hasRequests();
39 RPCRequestInfo GetNextRequest();
40 void RemoteDataReply(string channel, string message_id, string sdata, int idata); 41 void RemoteDataReply(string channel, string message_id, string sdata, int idata);
41 bool IsEnabled(); 42 bool IsEnabled();
42 void DeleteChannel(LLUUID itemID); 43 RPCRequestInfo GetNextCompletedRequest();
44 void RemoveCompletedRequest(LLUUID id);
45 void DeleteChannels(LLUUID itemID);
46 LLUUID SendRemoteData(uint localID, LLUUID itemID, string channel, string dest, int idata, string sdata);
47 SendRemoteDataRequest GetNextCompletedSRDRequest();
48 void RemoveCompletedSRDRequest(LLUUID id);
49 void CancelSRDRequests(LLUUID itemID);
43 } 50 }
44} \ No newline at end of file 51}
diff --git a/OpenSim/Region/Environment/Modules/ScriptsHttpRequests.cs b/OpenSim/Region/Environment/Modules/ScriptsHttpRequests.cs
index e3de13b..f38f354 100644
--- a/OpenSim/Region/Environment/Modules/ScriptsHttpRequests.cs
+++ b/OpenSim/Region/Environment/Modules/ScriptsHttpRequests.cs
@@ -184,13 +184,15 @@ namespace OpenSim.Region.Environment.Modules
184 184
185 public void StopHttpRequest(uint m_localID, LLUUID m_itemID) 185 public void StopHttpRequest(uint m_localID, LLUUID m_itemID)
186 { 186 {
187 lock (HttpListLock) 187 if(m_pendingRequests != null) {
188 { 188 lock (HttpListLock)
189 HttpRequestClass tmpReq;
190 if (m_pendingRequests.TryGetValue(m_itemID, out tmpReq))
191 { 189 {
192 tmpReq.Stop(); 190 HttpRequestClass tmpReq;
193 m_pendingRequests.Remove(m_itemID); 191 if (m_pendingRequests.TryGetValue(m_itemID, out tmpReq))
192 {
193 tmpReq.Stop();
194 m_pendingRequests.Remove(m_itemID);
195 }
194 } 196 }
195 } 197 }
196 } 198 }
@@ -216,7 +218,6 @@ namespace OpenSim.Region.Environment.Modules
216 { 218 {
217 if (tmpReq.finished) 219 if (tmpReq.finished)
218 { 220 {
219 m_pendingRequests.Remove(luid);
220 return tmpReq; 221 return tmpReq;
221 } 222 }
222 } 223 }
@@ -224,6 +225,21 @@ namespace OpenSim.Region.Environment.Modules
224 } 225 }
225 return null; 226 return null;
226 } 227 }
228
229 public void RemoveCompletedRequest(LLUUID id)
230 {
231 lock (HttpListLock)
232 {
233 HttpRequestClass tmpReq;
234 if (m_pendingRequests.TryGetValue(id, out tmpReq))
235 {
236 tmpReq.Stop();
237 tmpReq = null;
238 m_pendingRequests.Remove(id);
239 }
240 }
241 }
242
227 } 243 }
228 244
229 // 245 //
@@ -269,6 +285,7 @@ namespace OpenSim.Region.Environment.Modules
269 httpThread.Name = "HttpRequestThread"; 285 httpThread.Name = "HttpRequestThread";
270 httpThread.Priority = ThreadPriority.BelowNormal; 286 httpThread.Priority = ThreadPriority.BelowNormal;
271 httpThread.IsBackground = true; 287 httpThread.IsBackground = true;
288 finished = false;
272 httpThread.Start(); 289 httpThread.Start();
273 } 290 }
274 291
diff --git a/OpenSim/Region/Environment/Modules/WorldCommModule.cs b/OpenSim/Region/Environment/Modules/WorldCommModule.cs
index a426eda..b6d4e3d 100644
--- a/OpenSim/Region/Environment/Modules/WorldCommModule.cs
+++ b/OpenSim/Region/Environment/Modules/WorldCommModule.cs
@@ -84,8 +84,8 @@ namespace OpenSim.Region.Environment.Modules
84 m_scene = scene; 84 m_scene = scene;
85 m_scene.RegisterModuleInterface<IWorldComm>(this); 85 m_scene.RegisterModuleInterface<IWorldComm>(this);
86 m_listenerManager = new ListenerManager(); 86 m_listenerManager = new ListenerManager();
87 m_pending = new Queue<ListenerInfo>();
88 m_scene.EventManager.OnNewClient += NewClient; 87 m_scene.EventManager.OnNewClient += NewClient;
88 m_pending = new Queue<ListenerInfo>();
89 } 89 }
90 90
91 public void PostInitialise() 91 public void PostInitialise()
@@ -139,9 +139,12 @@ namespace OpenSim.Region.Environment.Modules
139 139
140 public void DeleteListener(LLUUID itemID) 140 public void DeleteListener(LLUUID itemID)
141 { 141 {
142 lock (ListLock) 142 if (m_listenerManager != null)
143 { 143 {
144 m_listenerManager.DeleteListener(itemID); 144 lock (ListLock)
145 {
146 m_listenerManager.DeleteListener(itemID);
147 }
145 } 148 }
146 149
147 } 150 }
@@ -167,14 +170,14 @@ namespace OpenSim.Region.Environment.Modules
167 // If they are in proximity, then if they are 170 // If they are in proximity, then if they are
168 // listeners, if so add them to the pending queue 171 // listeners, if so add them to the pending queue
169 172
170 foreach (LLUUID eb in m_scene.Entities.Keys) 173 foreach (ListenerInfo li in m_listenerManager.GetListeners())
171 { 174 {
172 EntityBase sPart; 175 EntityBase sPart;
173 176
174 m_scene.Entities.TryGetValue(eb, out sPart); 177 m_scene.Entities.TryGetValue(li.GetHostID(), out sPart);
175 178
176 // Dont process if this message is from itself! 179 // Dont process if this message is from itself!
177 if (eb.ToString().Equals(sourceItemID) || 180 if (li.GetHostID().ToString().Equals(sourceItemID) ||
178 sPart.UUID.ToString().Equals(sourceItemID)) 181 sPart.UUID.ToString().Equals(sourceItemID))
179 continue; 182 continue;
180 183
@@ -196,7 +199,10 @@ namespace OpenSim.Region.Environment.Modules
196 ); 199 );
197 if (isListener != null) 200 if (isListener != null)
198 { 201 {
199 m_pending.Enqueue(isListener); 202 lock (CommListLock)
203 {
204 m_pending.Enqueue(isListener);
205 }
200 } 206 }
201 } 207 }
202 break; 208 break;
@@ -210,7 +216,10 @@ namespace OpenSim.Region.Environment.Modules
210 ); 216 );
211 if (isListener != null) 217 if (isListener != null)
212 { 218 {
213 m_pending.Enqueue(isListener); 219 lock (CommListLock)
220 {
221 m_pending.Enqueue(isListener);
222 }
214 } 223 }
215 } 224 }
216 break; 225 break;
@@ -223,14 +232,17 @@ namespace OpenSim.Region.Environment.Modules
223 ); 232 );
224 if (isListener != null) 233 if (isListener != null)
225 { 234 {
226 m_pending.Enqueue(isListener); 235 lock (CommListLock)
236 {
237 m_pending.Enqueue(isListener);
238 }
227 } 239 }
228 } 240 }
229 break; 241 break;
230 242
231 case ChatTypeEnum.Broadcast: 243 case ChatTypeEnum.Broadcast:
232 ListenerInfo isListen = 244 ListenerInfo isListen =
233 m_listenerManager.IsListenerMatch(sourceItemID, eb, channel, name, msg); 245 m_listenerManager.IsListenerMatch(sourceItemID, li.GetItemID(), channel, name, msg);
234 if (isListen != null) 246 if (isListen != null)
235 { 247 {
236 ListenerInfo isListener = m_listenerManager.IsListenerMatch( 248 ListenerInfo isListener = m_listenerManager.IsListenerMatch(
@@ -238,19 +250,24 @@ namespace OpenSim.Region.Environment.Modules
238 ); 250 );
239 if (isListener != null) 251 if (isListener != null)
240 { 252 {
241 m_pending.Enqueue(isListener); 253 lock (CommListLock)
254 {
255 m_pending.Enqueue(isListener);
256 }
242 } 257 }
243 } 258 }
244 break; 259 break;
245 } 260 }
246 } 261 }
247 ;
248 } 262 }
249 } 263 }
250 264
251 public bool HasMessages() 265 public bool HasMessages()
252 { 266 {
253 return (m_pending.Count > 0); 267 if (m_pending != null)
268 return (m_pending.Count > 0);
269 else
270 return false;
254 } 271 }
255 272
256 public ListenerInfo GetNextMessage() 273 public ListenerInfo GetNextMessage()
@@ -264,6 +281,17 @@ namespace OpenSim.Region.Environment.Modules
264 281
265 return li; 282 return li;
266 } 283 }
284
285 public uint PeekNextMessageLocalID()
286 {
287 return m_pending.Peek().GetLocalID();
288 }
289
290 public LLUUID PeekNextMessageItemID()
291 {
292 return m_pending.Peek().GetItemID();
293 }
294
267 } 295 }
268 296
269 // hostID: the ID of the ScenePart 297 // hostID: the ID of the ScenePart
@@ -280,8 +308,7 @@ namespace OpenSim.Region.Environment.Modules
280 m_listeners = new Dictionary<int, ListenerInfo>(); 308 m_listeners = new Dictionary<int, ListenerInfo>();
281 } 309 }
282 310
283 public int AddListener(uint localID, LLUUID itemID, LLUUID hostID, int channel, string name, string id, 311 public int AddListener(uint localID, LLUUID itemID, LLUUID hostID, int channel, string name, string id, string msg)
284 string msg)
285 { 312 {
286 if (m_listeners.Count < m_MaxListeners) 313 if (m_listeners.Count < m_MaxListeners)
287 { 314 {
@@ -410,6 +437,11 @@ namespace OpenSim.Region.Environment.Modules
410 } 437 }
411 return null; 438 return null;
412 } 439 }
440
441 public Dictionary<int, ListenerInfo>.ValueCollection GetListeners()
442 {
443 return m_listeners.Values;
444 }
413 } 445 }
414 446
415 public class ListenerInfo 447 public class ListenerInfo
@@ -425,21 +457,20 @@ namespace OpenSim.Region.Environment.Modules
425 private string m_message; // The message 457 private string m_message; // The message
426 private bool m_active; // Listener is active or not 458 private bool m_active; // Listener is active or not
427 459
428 public ListenerInfo(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, LLUUID id, 460 public ListenerInfo(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, LLUUID id, string message)
429 string message)
430 { 461 {
431 Initialise(localID, handle, ItemID, hostID, channel, name, id, message); 462 Initialise(localID, handle, ItemID, hostID, channel, name, id, message);
432 } 463 }
433 464
434 public ListenerInfo(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, LLUUID id, 465 public ListenerInfo(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, LLUUID id,
435 string message, LLUUID sourceItemID) 466 string message, LLUUID sourceItemID)
436 { 467 {
437 Initialise(localID, handle, ItemID, hostID, channel, name, id, message); 468 Initialise(localID, handle, ItemID, hostID, channel, name, id, message);
438 m_sourceItemID = sourceItemID; 469 m_sourceItemID = sourceItemID;
439 } 470 }
440 471
441 private void Initialise(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, 472 private void Initialise(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name,
442 LLUUID id, string message) 473 LLUUID id, string message)
443 { 474 {
444 m_handle = handle; 475 m_handle = handle;
445 m_channel = channel; 476 m_channel = channel;
@@ -511,5 +542,6 @@ namespace OpenSim.Region.Environment.Modules
511 { 542 {
512 return m_id; 543 return m_id;
513 } 544 }
545
514 } 546 }
515} \ No newline at end of file 547}
diff --git a/OpenSim/Region/Environment/Modules/XMLRPCModule.cs b/OpenSim/Region/Environment/Modules/XMLRPCModule.cs
index edd1df8..48a4c7c 100644
--- a/OpenSim/Region/Environment/Modules/XMLRPCModule.cs
+++ b/OpenSim/Region/Environment/Modules/XMLRPCModule.cs
@@ -78,19 +78,20 @@ namespace OpenSim.Region.Environment.Modules
78 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 78 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
79 79
80 private Scene m_scene; 80 private Scene m_scene;
81 private Queue<RPCRequestInfo> rpcQueue = new Queue<RPCRequestInfo>();
82 private object XMLRPCListLock = new object(); 81 private object XMLRPCListLock = new object();
83 private string m_name = "XMLRPCModule"; 82 private string m_name = "XMLRPCModule";
84 private int RemoteReplyScriptWait = 300; 83 private int RemoteReplyScriptWait = 300;
85 private int RemoteReplyScriptTimeout = 900; 84 private int RemoteReplyScriptTimeout = 9000;
86 private int m_remoteDataPort = 0; 85 private int m_remoteDataPort = 0;
87 private List<Scene> m_scenes = new List<Scene>(); 86 private List<Scene> m_scenes = new List<Scene>();
88 87
89 // <channel id, RPCChannelInfo> 88 // <channel id, RPCChannelInfo>
90 private Dictionary<LLUUID, RPCChannelInfo> m_openChannels; 89 private Dictionary<LLUUID, RPCChannelInfo> m_openChannels;
91 90
92 // <channel id, RPCRequestInfo> 91 private Dictionary<LLUUID, RPCRequestInfo> m_rpcPending;
93 private Dictionary<LLUUID, RPCRequestInfo> m_pendingResponse; 92 private Dictionary<LLUUID, RPCRequestInfo> m_rpcPendingResponses;
93
94 private Dictionary<LLUUID, SendRemoteDataRequest> m_pendingSRDResponses;
94 95
95 public void Initialise(Scene scene, IConfigSource config) 96 public void Initialise(Scene scene, IConfigSource config)
96 { 97 {
@@ -115,13 +116,15 @@ namespace OpenSim.Region.Environment.Modules
115 if (IsEnabled()) 116 if (IsEnabled())
116 { 117 {
117 m_openChannels = new Dictionary<LLUUID, RPCChannelInfo>(); 118 m_openChannels = new Dictionary<LLUUID, RPCChannelInfo>();
118 m_pendingResponse = new Dictionary<LLUUID, RPCRequestInfo>(); 119 m_rpcPending = new Dictionary<LLUUID, RPCRequestInfo>();
120 m_rpcPendingResponses = new Dictionary<LLUUID, RPCRequestInfo>();
121 m_pendingSRDResponses = new Dictionary<LLUUID, SendRemoteDataRequest>();
119 122
120 // Start http server 123 // Start http server
121 // Attach xmlrpc handlers 124 // Attach xmlrpc handlers
122 m_log.Info("[REMOTE_DATA]: " + 125 m_log.Info("[REMOTE_DATA]: " +
123 "Starting XMLRPC Server on port " + m_remoteDataPort + " for llRemoteData commands."); 126 "Starting XMLRPC Server on port " + m_remoteDataPort + " for llRemoteData commands.");
124 BaseHttpServer httpServer = new BaseHttpServer((uint) m_remoteDataPort); 127 BaseHttpServer httpServer = new BaseHttpServer((uint)m_remoteDataPort);
125 httpServer.AddXmlRPCHandler("llRemoteData", XmlRpcRemoteData); 128 httpServer.AddXmlRPCHandler("llRemoteData", XmlRpcRemoteData);
126 httpServer.Start(); 129 httpServer.Start();
127 } 130 }
@@ -188,18 +191,28 @@ namespace OpenSim.Region.Environment.Modules
188 return channel; 191 return channel;
189 } 192 }
190 193
191 public void DeleteChannel(LLUUID itemID) 194 // Delete channels based on itemID
195 // for when a script is deleted
196 public void DeleteChannels(LLUUID itemID)
192 { 197 {
193 198
194 foreach (RPCChannelInfo li in m_openChannels.Values) 199 if (m_openChannels != null)
195 { 200 {
201 ArrayList tmp = new ArrayList();
196 202
197 if (li.GetItemID().Equals(itemID)) 203 lock (XMLRPCListLock)
198 { 204 {
205 foreach (RPCChannelInfo li in m_openChannels.Values)
206 {
207 if (li.GetItemID().Equals(itemID))
208 {
209 tmp.Add(itemID);
210 }
211 }
199 212
200 m_openChannels.Remove(li.GetChannelID()); 213 System.Collections.IEnumerator tmpEnumerator = tmp.GetEnumerator();
201 return; 214 while ( tmpEnumerator.MoveNext() )
202 215 m_openChannels.Remove((LLUUID)tmpEnumerator.Current);
203 } 216 }
204 217
205 } 218 }
@@ -218,15 +231,12 @@ namespace OpenSim.Region.Environment.Modules
218 RPCRequestInfo rpcInfo; 231 RPCRequestInfo rpcInfo;
219 LLUUID message_key = new LLUUID(message_id); 232 LLUUID message_key = new LLUUID(message_id);
220 233
221 if (m_pendingResponse.TryGetValue(message_key, out rpcInfo)) 234 if (m_rpcPendingResponses.TryGetValue(message_key, out rpcInfo))
222 { 235 {
223 rpcInfo.SetRetval(sdata); 236 rpcInfo.SetStrRetval(sdata);
237 rpcInfo.SetIntRetval(idata);
224 rpcInfo.SetProcessed(true); 238 rpcInfo.SetProcessed(true);
225 239 m_rpcPendingResponses.Remove(message_key);
226 lock (XMLRPCListLock)
227 {
228 m_pendingResponse.Remove(message_key);
229 }
230 } 240 }
231 } 241 }
232 242
@@ -248,18 +258,18 @@ namespace OpenSim.Region.Environment.Modules
248 { 258 {
249 XmlRpcResponse response = new XmlRpcResponse(); 259 XmlRpcResponse response = new XmlRpcResponse();
250 260
251 Hashtable requestData = (Hashtable) request.Params[0]; 261 Hashtable requestData = (Hashtable)request.Params[0];
252 bool GoodXML = (requestData.Contains("Channel") && requestData.Contains("IntValue") && 262 bool GoodXML = (requestData.Contains("Channel") && requestData.Contains("IntValue") &&
253 requestData.Contains("StringValue")); 263 requestData.Contains("StringValue"));
254 264
255 if (GoodXML) 265 if (GoodXML)
256 { 266 {
257 LLUUID channel = new LLUUID((string) requestData["Channel"]); 267 LLUUID channel = new LLUUID((string)requestData["Channel"]);
258 RPCChannelInfo rpcChanInfo; 268 RPCChannelInfo rpcChanInfo;
259 if (m_openChannels.TryGetValue(channel, out rpcChanInfo)) 269 if (m_openChannels.TryGetValue(channel, out rpcChanInfo))
260 { 270 {
261 string intVal = (string) requestData["IntValue"]; 271 string intVal = (string)requestData["IntValue"];
262 string strVal = (string) requestData["StringValue"]; 272 string strVal = (string)requestData["StringValue"];
263 273
264 RPCRequestInfo rpcInfo; 274 RPCRequestInfo rpcInfo;
265 275
@@ -268,7 +278,7 @@ namespace OpenSim.Region.Environment.Modules
268 rpcInfo = 278 rpcInfo =
269 new RPCRequestInfo(rpcChanInfo.GetLocalID(), rpcChanInfo.GetItemID(), channel, strVal, 279 new RPCRequestInfo(rpcChanInfo.GetLocalID(), rpcChanInfo.GetItemID(), channel, strVal,
270 intVal); 280 intVal);
271 rpcQueue.Enqueue(rpcInfo); 281 m_rpcPending.Add(rpcInfo.GetMessageID(), rpcInfo);
272 } 282 }
273 283
274 int timeoutCtr = 0; 284 int timeoutCtr = 0;
@@ -280,16 +290,20 @@ namespace OpenSim.Region.Environment.Modules
280 } 290 }
281 if (rpcInfo.IsProcessed()) 291 if (rpcInfo.IsProcessed())
282 { 292 {
283 response.Value = rpcInfo.GetRetval(); 293 Hashtable param = new Hashtable();
294 param["StringValue"] = rpcInfo.GetStrRetval();
295 param["IntValue"] = Convert.ToString(rpcInfo.GetIntRetval());
296
297 ArrayList parameters = new ArrayList();
298 parameters.Add(param);
299
300 response.Value = parameters;
284 rpcInfo = null; 301 rpcInfo = null;
285 } 302 }
286 else 303 else
287 { 304 {
288 response.SetFault(-1, "Script timeout"); 305 response.SetFault(-1, "Script timeout");
289 lock (XMLRPCListLock) 306 rpcInfo = null;
290 {
291 m_pendingResponse.Remove(rpcInfo.GetMessageID());
292 }
293 } 307 }
294 } 308 }
295 else 309 else
@@ -303,129 +317,365 @@ namespace OpenSim.Region.Environment.Modules
303 317
304 public bool hasRequests() 318 public bool hasRequests()
305 { 319 {
306 return (rpcQueue.Count > 0);
307 }
308
309 public RPCRequestInfo GetNextRequest()
310 {
311 lock (XMLRPCListLock) 320 lock (XMLRPCListLock)
312 { 321 {
313 RPCRequestInfo rpcInfo = rpcQueue.Dequeue(); 322 if (m_rpcPending != null)
314 m_pendingResponse.Add(rpcInfo.GetMessageID(), rpcInfo); 323 return (m_rpcPending.Count > 0);
315 return rpcInfo; 324 else
325 return false;
316 } 326 }
317 } 327 }
318 }
319
320 /**************************************************************
321 *
322 * Class RPCRequestInfo
323 *
324 * Holds details about incoming requests until they are picked
325 * from the queue by LSLLongCmdHandler
326 * ***********************************************************/
327 328
328 public class RPCRequestInfo 329 public RPCRequestInfo GetNextCompletedRequest()
329 {
330 private string m_StrVal;
331 private string m_IntVal;
332 private bool m_processed;
333 private string m_resp;
334 private uint m_localID;
335 private LLUUID m_ItemID;
336 private LLUUID m_MessageID;
337 private LLUUID m_ChannelKey;
338
339 public RPCRequestInfo(uint localID, LLUUID itemID, LLUUID channelKey, string strVal, string intVal)
340 { 330 {
341 m_localID = localID; 331 if (m_rpcPending != null)
342 m_StrVal = strVal; 332 {
343 m_IntVal = intVal; 333 lock (XMLRPCListLock)
344 m_ItemID = itemID; 334 {
345 m_ChannelKey = channelKey; 335 foreach (LLUUID luid in m_rpcPending.Keys)
346 m_MessageID = LLUUID.Random(); 336 {
347 m_processed = false; 337 RPCRequestInfo tmpReq;
348 m_resp = String.Empty;
349 }
350 338
351 public bool IsProcessed() 339 if (m_rpcPending.TryGetValue(luid, out tmpReq))
352 { 340 {
353 return m_processed;
354 }
355 341
356 public LLUUID GetChannelKey() 342 if (!tmpReq.IsProcessed()) return tmpReq;
357 { 343 }
358 return m_ChannelKey; 344 }
345 }
346 }
347 return null;
359 } 348 }
360 349
361 public void SetProcessed(bool processed) 350 public void RemoveCompletedRequest(LLUUID id)
362 { 351 {
363 m_processed = processed; 352 lock (XMLRPCListLock)
353 {
354 RPCRequestInfo tmp;
355 if (m_rpcPending.TryGetValue(id, out tmp))
356 {
357 m_rpcPending.Remove(id);
358 m_rpcPendingResponses.Add(id, tmp);
359 }
360 else
361 {
362 Console.WriteLine("UNABLE TO REMOVE COMPLETED REQUEST");
363 }
364 }
364 } 365 }
365 366
366 public void SetRetval(string resp) 367 public LLUUID SendRemoteData(uint localID, LLUUID itemID, string channel, string dest, int idata, string sdata)
367 { 368 {
368 m_resp = resp;
369 }
370 369
371 public string GetRetval() 370 SendRemoteDataRequest req = new SendRemoteDataRequest(
372 { 371 localID, itemID, channel, dest, idata, sdata
373 return m_resp; 372 );
374 } 373 m_pendingSRDResponses.Add(req.GetReqID(), req);
374 return req.process();
375 375
376 public uint GetLocalID()
377 {
378 return m_localID;
379 } 376 }
380 377
381 public LLUUID GetItemID() 378 public SendRemoteDataRequest GetNextCompletedSRDRequest()
382 { 379 {
383 return m_ItemID; 380 if (m_pendingSRDResponses != null)
384 } 381 {
382 lock (XMLRPCListLock)
383 {
384 foreach (LLUUID luid in m_pendingSRDResponses.Keys)
385 {
386 SendRemoteDataRequest tmpReq;
385 387
386 public string GetStrVal() 388 if (m_pendingSRDResponses.TryGetValue(luid, out tmpReq))
387 { 389 {
388 return m_StrVal; 390 if (tmpReq.finished)
391 return tmpReq;
392 }
393 }
394 }
395 }
396 return null;
389 } 397 }
390 398
391 public int GetIntValue() 399 public void RemoveCompletedSRDRequest(LLUUID id)
392 { 400 {
393 return int.Parse(m_IntVal); 401 lock (XMLRPCListLock)
402 {
403 SendRemoteDataRequest tmpReq;
404 if (m_pendingSRDResponses.TryGetValue(id, out tmpReq))
405 {
406 m_pendingSRDResponses.Remove(id);
407 }
408 }
394 } 409 }
395 410
396 public LLUUID GetMessageID() 411 public void CancelSRDRequests(LLUUID itemID)
397 { 412 {
398 return m_MessageID; 413 if (m_pendingSRDResponses != null)
414 {
415 lock (XMLRPCListLock)
416 {
417 foreach (SendRemoteDataRequest li in m_pendingSRDResponses.Values)
418 {
419 if (li.m_itemID.Equals(itemID))
420 m_pendingSRDResponses.Remove(li.GetReqID());
421 }
422 }
423 }
399 } 424 }
400 } 425 }
426 /**************************************************************
427 *
428 * Class RPCRequestInfo
429 *
430 * Holds details about incoming requests until they are picked
431 * from the queue by LSLLongCmdHandler
432 * ***********************************************************/
401 433
402 public class RPCChannelInfo 434 public class RPCRequestInfo
403 {
404 private LLUUID m_itemID;
405 private uint m_localID;
406 private LLUUID m_ChannelKey;
407
408 public RPCChannelInfo(uint localID, LLUUID itemID, LLUUID channelID)
409 { 435 {
410 m_ChannelKey = channelID; 436 private string m_StrVal;
411 m_localID = localID; 437 private string m_IntVal;
412 m_itemID = itemID; 438 private bool m_processed;
413 } 439 private string m_respStr;
440 private int m_respInt;
441 private uint m_localID;
442 private LLUUID m_ItemID;
443 private LLUUID m_MessageID;
444 private LLUUID m_ChannelKey;
445
446 public RPCRequestInfo(uint localID, LLUUID itemID, LLUUID channelKey, string strVal, string intVal)
447 {
448 m_localID = localID;
449 m_StrVal = strVal;
450 m_IntVal = intVal;
451 m_ItemID = itemID;
452 m_ChannelKey = channelKey;
453 m_MessageID = LLUUID.Random();
454 m_processed = false;
455 m_respStr = String.Empty;
456 m_respInt = 0;
457 }
414 458
415 public LLUUID GetItemID() 459 public bool IsProcessed()
416 { 460 {
417 return m_itemID; 461 return m_processed;
462 }
463
464 public LLUUID GetChannelKey()
465 {
466 return m_ChannelKey;
467 }
468
469 public void SetProcessed(bool processed)
470 {
471 m_processed = processed;
472 }
473
474 public void SetStrRetval(string resp)
475 {
476 m_respStr = resp;
477 }
478
479 public string GetStrRetval()
480 {
481 return m_respStr;
482 }
483 public void SetIntRetval(int resp)
484 {
485 m_respInt = resp;
486 }
487
488 public int GetIntRetval()
489 {
490 return m_respInt;
491 }
492 public uint GetLocalID()
493 {
494 return m_localID;
495 }
496
497 public LLUUID GetItemID()
498 {
499 return m_ItemID;
500 }
501
502 public string GetStrVal()
503 {
504 return m_StrVal;
505 }
506
507 public int GetIntValue()
508 {
509 return int.Parse(m_IntVal);
510 }
511
512 public LLUUID GetMessageID()
513 {
514 return m_MessageID;
515 }
418 } 516 }
419 517
420 public LLUUID GetChannelID() 518 public class RPCChannelInfo
421 { 519 {
422 return m_ChannelKey; 520 private LLUUID m_itemID;
521 private uint m_localID;
522 private LLUUID m_ChannelKey;
523
524 public RPCChannelInfo(uint localID, LLUUID itemID, LLUUID channelID)
525 {
526 m_ChannelKey = channelID;
527 m_localID = localID;
528 m_itemID = itemID;
529 }
530
531 public LLUUID GetItemID()
532 {
533 return m_itemID;
534 }
535
536 public LLUUID GetChannelID()
537 {
538 return m_ChannelKey;
539 }
540
541 public uint GetLocalID()
542 {
543 return m_localID;
544 }
545
423 } 546 }
424 547
425 public uint GetLocalID() 548 public class SendRemoteDataRequest
426 { 549 {
427 return m_localID; 550
551 public LLUUID reqID;
552 public string destURL;
553 public string channel;
554 public string sdata;
555 public int idata;
556 public bool finished;
557 public string response_sdata;
558 public int response_idata;
559 public XmlRpcRequest request;
560 private Thread httpThread;
561 public LLUUID m_itemID;
562 public uint m_localID;
563 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
564
565 public SendRemoteDataRequest(uint localID, LLUUID itemID, string channel, string dest, int idata, string sdata)
566 {
567
568 this.channel = channel;
569 this.destURL = dest;
570 this.idata = idata;
571 this.sdata = sdata;
572 m_itemID = itemID;
573 m_localID = localID;
574
575 reqID = LLUUID.Random();
576
577 }
578
579 public LLUUID process()
580 {
581 httpThread = new Thread(SendRequest);
582 httpThread.Name = "HttpRequestThread";
583 httpThread.Priority = ThreadPriority.BelowNormal;
584 httpThread.IsBackground = true;
585 finished = false;
586 httpThread.Start();
587
588 return reqID;
589
590 }
591
592 /*
593 * TODO: More work on the response codes. Right now
594 * returning 200 for success or 499 for exception
595 */
596
597 public void SendRequest()
598 {
599
600 Hashtable param = new Hashtable();
601
602 // Check if channel is an LLUUID
603 // if not, use as method name
604 LLUUID parseUID;
605 string mName = "llRemoteData";
606 if( (channel != null) && (channel != "") )
607 if( !LLUUID.TryParse(channel, out parseUID) )
608 mName = channel;
609 else
610 param["Channel"] = channel;
611
612 param["StringValue"] = sdata;
613 param["IntValue"] = Convert.ToString(idata);
614
615 ArrayList parameters = new ArrayList();
616 parameters.Add(param);
617 XmlRpcRequest req = new XmlRpcRequest(mName, parameters);
618 try
619 {
620 XmlRpcResponse resp = req.Send(destURL, 30000);
621 if (resp != null)
622 {
623 Hashtable respParms;
624 if(resp.Value.GetType().Equals(Type.GetType("System.Collections.Hashtable"))) {
625 respParms = (Hashtable)resp.Value;
626 }
627 else {
628 ArrayList respData = (ArrayList)resp.Value;
629 respParms = (Hashtable)respData[0];
630 }
631 if (respParms != null)
632 {
633 if (respParms.Contains("StringValue"))
634 {
635 sdata = (string)respParms["StringValue"];
636 }
637 if (respParms.Contains("IntValue"))
638 {
639 idata = Convert.ToInt32((string)respParms["IntValue"]);
640 }
641 if (respParms.Contains("faultString"))
642 {
643 sdata = (string)respParms["faultString"];
644 }
645 if (respParms.Contains("faultCode"))
646 {
647 idata = Convert.ToInt32(respParms["faultCode"]);
648 }
649 }
650 }
651 }
652 catch (System.Net.WebException we)
653 {
654 sdata = we.Message;
655 m_log.Warn("[SendRemoteDataRequest]: Request failed");
656 m_log.Warn(we.StackTrace);
657 }
658
659 finished = true;
660
661 }
662
663 public void Stop()
664 {
665 try
666 {
667 httpThread.Abort();
668 }
669 catch (Exception)
670 {
671 }
672 }
673
674 public LLUUID GetReqID()
675 {
676 return reqID;
677 }
678
428 } 679 }
429 680
430 } 681} \ No newline at end of file
431}
diff --git a/OpenSim/Region/ScriptEngine/Common/LSL_BaseClass.cs b/OpenSim/Region/ScriptEngine/Common/LSL_BaseClass.cs
index 7713490..60a1cb3 100644
--- a/OpenSim/Region/ScriptEngine/Common/LSL_BaseClass.cs
+++ b/OpenSim/Region/ScriptEngine/Common/LSL_BaseClass.cs
@@ -2091,6 +2091,10 @@ namespace OpenSim.Region.ScriptEngine.Common
2091 public const int REMOTE_DATA_CHANNEL = 1; 2091 public const int REMOTE_DATA_CHANNEL = 1;
2092 public const int REMOTE_DATA_REQUEST = 2; 2092 public const int REMOTE_DATA_REQUEST = 2;
2093 public const int REMOTE_DATA_REPLY = 3; 2093 public const int REMOTE_DATA_REPLY = 3;
2094 public const int HTTP_METHOD = 0;
2095 public const int HTTP_MIMETYPE = 1;
2096 public const int HTTP_BODY_MAXLENGTH = 2;
2097 public const int HTTP_VERIFY_CERT = 3;
2094 2098
2095 public const int PRIM_MATERIAL = 2; 2099 public const int PRIM_MATERIAL = 2;
2096 public const int PRIM_PHYSICS = 3; 2100 public const int PRIM_PHYSICS = 3;
diff --git a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs
index c07f6d7..1ab2a43 100644
--- a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs
+++ b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs
@@ -2880,8 +2880,8 @@ namespace OpenSim.Region.ScriptEngine.Common
2880 public string llSendRemoteData(string channel, string dest, int idata, string sdata) 2880 public string llSendRemoteData(string channel, string dest, int idata, string sdata)
2881 { 2881 {
2882 m_host.AddScriptLPS(1); 2882 m_host.AddScriptLPS(1);
2883 NotImplemented("llSendRemoteData"); 2883 IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
2884 return String.Empty; 2884 return (xmlrpcMod.SendRemoteData(m_localID, m_itemID, channel, dest, idata, sdata)).ToString();
2885 } 2885 }
2886 2886
2887 public void llRemoteDataReply(string channel, string message_id, string sdata, int idata) 2887 public void llRemoteDataReply(string channel, string message_id, string sdata, int idata)
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs
index 1afe71c..0491612 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/AsyncLSLCommandManager.cs
@@ -125,8 +125,10 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
125 comms.DeleteListener(itemID); 125 comms.DeleteListener(itemID);
126 126
127 IXMLRPC xmlrpc = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>(); 127 IXMLRPC xmlrpc = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
128 xmlrpc.DeleteChannel(itemID); 128 xmlrpc.DeleteChannels(itemID);
129 129
130 xmlrpc.CancelSRDRequests(itemID);
131
130 } 132 }
131 133
132 #region TIMER 134 #region TIMER
@@ -238,24 +240,29 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
238 // implemented here yet anyway. Should be fixed if/when maxsize 240 // implemented here yet anyway. Should be fixed if/when maxsize
239 // is supported 241 // is supported
240 242
241 object[] resobj = new object[] 243 if (m_ScriptEngine.m_ScriptManager.GetScript(httpInfo.localID, httpInfo.itemID) != null)
244 {
245 iHttpReq.RemoveCompletedRequest(httpInfo.reqID);
246 object[] resobj = new object[]
242 { 247 {
243 httpInfo.reqID.ToString(), httpInfo.status, null, httpInfo.response_body 248 httpInfo.reqID.ToString(), httpInfo.status, null, httpInfo.response_body
244 }; 249 };
245 250
246 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( 251 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
247 httpInfo.localID, httpInfo.itemID, "http_response", EventQueueManager.llDetectNull, resobj 252 httpInfo.localID, httpInfo.itemID, "http_response", EventQueueManager.llDetectNull, resobj
248 ); 253 );
249 254
250 httpInfo.Stop(); 255 }
251 httpInfo = null;
252 256
253 httpInfo = iHttpReq.GetNextCompletedRequest(); 257 httpInfo = iHttpReq.GetNextCompletedRequest();
258
254 } 259 }
255 } 260 }
256 261
257 #endregion 262 #endregion
258 263
264 #region Check llRemoteData channels
265
259 public void CheckXMLRPCRequests() 266 public void CheckXMLRPCRequests()
260 { 267 {
261 if (m_ScriptEngine.World == null) 268 if (m_ScriptEngine.World == null)
@@ -265,47 +272,96 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
265 272
266 if (xmlrpc != null) 273 if (xmlrpc != null)
267 { 274 {
268 while (xmlrpc.hasRequests()) 275 RPCRequestInfo rInfo = xmlrpc.GetNextCompletedRequest();
276
277 while (rInfo != null)
269 { 278 {
270 RPCRequestInfo rInfo = xmlrpc.GetNextRequest(); 279 if (m_ScriptEngine.m_ScriptManager.GetScript(rInfo.GetLocalID(), rInfo.GetItemID()) != null)
271 //Console.WriteLine("PICKED REQUEST"); 280 {
281 xmlrpc.RemoveCompletedRequest(rInfo.GetMessageID());
272 282
273 //Deliver data to prim's remote_data handler 283 //Deliver data to prim's remote_data handler
274 object[] resobj = new object[] 284 object[] resobj = new object[]
275 { 285 {
276 2, rInfo.GetChannelKey().ToString(), rInfo.GetMessageID().ToString(), String.Empty, 286 2, rInfo.GetChannelKey().ToString(), rInfo.GetMessageID().ToString(), String.Empty,
277 rInfo.GetIntValue(), 287 rInfo.GetIntValue(),
278 rInfo.GetStrVal() 288 rInfo.GetStrVal()
279 }; 289 };
280 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( 290 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
281 rInfo.GetLocalID(), rInfo.GetItemID(), "remote_data", EventQueueManager.llDetectNull, resobj 291 rInfo.GetLocalID(), rInfo.GetItemID(), "remote_data", EventQueueManager.llDetectNull, resobj
282 ); 292 );
293
294 }
295
296 rInfo = xmlrpc.GetNextCompletedRequest();
297
283 } 298 }
299
300 SendRemoteDataRequest srdInfo = xmlrpc.GetNextCompletedSRDRequest();
301
302 while (srdInfo != null)
303 {
304 if (m_ScriptEngine.m_ScriptManager.GetScript(srdInfo.m_localID, srdInfo.m_itemID) != null)
305 {
306 xmlrpc.RemoveCompletedSRDRequest(srdInfo.GetReqID());
307
308 //Deliver data to prim's remote_data handler
309 object[] resobj = new object[]
310 {
311 3, srdInfo.channel.ToString(), srdInfo.GetReqID().ToString(), String.Empty,
312 srdInfo.idata,
313 srdInfo.sdata
314 };
315 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
316 srdInfo.m_localID, srdInfo.m_itemID, "remote_data", EventQueueManager.llDetectNull, resobj
317 );
318
319 }
320
321 srdInfo = xmlrpc.GetNextCompletedSRDRequest();
322
323 }
324
325
284 } 326 }
285 } 327 }
286 328
329 #endregion
330
331 #region Check llListeners
332
287 public void CheckListeners() 333 public void CheckListeners()
288 { 334 {
289 if (m_ScriptEngine.World == null) 335 if (m_ScriptEngine.World == null)
290 return; 336 return;
291 IWorldComm comms = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 337 IWorldComm comms = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
292 338
293 while (comms.HasMessages()) 339 if (comms != null)
294 { 340 {
295 ListenerInfo lInfo = comms.GetNextMessage(); 341 while (comms.HasMessages())
296 342 {
297 //Deliver data to prim's listen handler 343 if (m_ScriptEngine.m_ScriptManager.GetScript(
298 object[] resobj = new object[] 344 comms.PeekNextMessageLocalID(), comms.PeekNextMessageItemID()) != null)
299 { 345 {
300 lInfo.GetChannel(), lInfo.GetName(), lInfo.GetID().ToString(), lInfo.GetMessage() 346 ListenerInfo lInfo = comms.GetNextMessage();
301 };
302 347
303 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue( 348 //Deliver data to prim's listen handler
304 lInfo.GetLocalID(), lInfo.GetItemID(), "listen", EventQueueManager.llDetectNull, resobj 349 object[] resobj = new object[]
305 ); 350 {
351 lInfo.GetChannel(), lInfo.GetName(), lInfo.GetID().ToString(), lInfo.GetMessage()
352 };
353
354 m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
355 lInfo.GetLocalID(), lInfo.GetItemID(), "listen", EventQueueManager.llDetectNull, resobj
356 );
357 }
358
359 }
306 } 360 }
307 } 361 }
308 362
363 #endregion
364
309 /// <summary> 365 /// <summary>
310 /// If set to true then threads and stuff should try to make a graceful exit 366 /// If set to true then threads and stuff should try to make a graceful exit
311 /// </summary> 367 /// </summary>
@@ -317,4 +373,4 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
317 private bool _PleaseShutdown = false; 373 private bool _PleaseShutdown = false;
318 374
319 } 375 }
320} \ No newline at end of file 376}
diff --git a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs
index 641453e..d47cab8 100644
--- a/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ScriptEngineBase/ScriptManager.cs
@@ -67,6 +67,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
67 private Queue<LUStruct> LUQueue = new Queue<LUStruct>(); 67 private Queue<LUStruct> LUQueue = new Queue<LUStruct>();
68 private static bool PrivateThread; 68 private static bool PrivateThread;
69 private int LoadUnloadMaxQueueSize; 69 private int LoadUnloadMaxQueueSize;
70 private Object scriptLock = new Object();
70 71
71 // Load/Unload structure 72 // Load/Unload structure
72 private struct LUStruct 73 private struct LUStruct
@@ -304,7 +305,9 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
304 //ScriptBaseInterface Script = (ScriptBaseInterface)GetScript(localID, itemID); 305 //ScriptBaseInterface Script = (ScriptBaseInterface)GetScript(localID, itemID);
305 IScript Script = GetScript(localID, itemID); 306 IScript Script = GetScript(localID, itemID);
306 if (Script == null) 307 if (Script == null)
308 {
307 return; 309 return;
310 }
308//cfk 2-7-08 dont need this right now and the default Linux build has DEBUG defined 311//cfk 2-7-08 dont need this right now and the default Linux build has DEBUG defined
309///#if DEBUG 312///#if DEBUG
310/// Console.WriteLine("ScriptEngine: Executing event: " + FunctionName); 313/// Console.WriteLine("ScriptEngine: Executing event: " + FunctionName);
@@ -331,37 +334,42 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
331 334
332 public IScript GetScript(uint localID, LLUUID itemID) 335 public IScript GetScript(uint localID, LLUUID itemID)
333 { 336 {
334 if (Scripts.ContainsKey(localID) == false) 337 lock (scriptLock)
335 return null; 338 {
336 339 if (Scripts.ContainsKey(localID) == false)
337 Dictionary<LLUUID, IScript> Obj; 340 return null;
338 Scripts.TryGetValue(localID, out Obj); 341
339 if (Obj.ContainsKey(itemID) == false) 342 Dictionary<LLUUID, IScript> Obj;
340 return null; 343 Scripts.TryGetValue(localID, out Obj);
341 344 if (Obj.ContainsKey(itemID) == false)
342 // Get script 345 return null;
343 IScript Script; 346
344 Obj.TryGetValue(itemID, out Script); 347 // Get script
345 348 IScript Script;
346 return Script; 349 Obj.TryGetValue(itemID, out Script);
350 return Script;
351 }
347 } 352 }
348 353
349 public void SetScript(uint localID, LLUUID itemID, IScript Script) 354 public void SetScript(uint localID, LLUUID itemID, IScript Script)
350 { 355 {
351 // Create object if it doesn't exist 356 lock (scriptLock)
352 if (Scripts.ContainsKey(localID) == false)
353 { 357 {
354 Scripts.Add(localID, new Dictionary<LLUUID, IScript>()); 358 // Create object if it doesn't exist
355 } 359 if (Scripts.ContainsKey(localID) == false)
360 {
361 Scripts.Add(localID, new Dictionary<LLUUID, IScript>());
362 }
356 363
357 // Delete script if it exists 364 // Delete script if it exists
358 Dictionary<LLUUID, IScript> Obj; 365 Dictionary<LLUUID, IScript> Obj;
359 Scripts.TryGetValue(localID, out Obj); 366 Scripts.TryGetValue(localID, out Obj);
360 if (Obj.ContainsKey(itemID) == true) 367 if (Obj.ContainsKey(itemID) == true)
361 Obj.Remove(itemID); 368 Obj.Remove(itemID);
362 369
363 // Add to object 370 // Add to object
364 Obj.Add(itemID, Script); 371 Obj.Add(itemID, Script);
372 }
365 } 373 }
366 374
367 public void RemoveScript(uint localID, LLUUID itemID) 375 public void RemoveScript(uint localID, LLUUID itemID)