aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
-rw-r--r--OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs326
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs133
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs14
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs10
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs14
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs85
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs8
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XWorkItem.cs6
10 files changed, 372 insertions, 228 deletions
diff --git a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
index 35ae44c..b9a217b 100644
--- a/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Interfaces/IScriptInstance.cs
@@ -51,7 +51,7 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
51 public interface IScriptWorkItem 51 public interface IScriptWorkItem
52 { 52 {
53 bool Cancel(); 53 bool Cancel();
54 void Abort(); 54 bool Abort();
55 55
56 /// <summary> 56 /// <summary>
57 /// Wait for the work item to complete. 57 /// Wait for the work item to complete.
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 6879ebb..1e19032 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -37,6 +37,8 @@ using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared; 37using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; 38using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
39using Timer=OpenSim.Region.ScriptEngine.Shared.Api.Plugins.Timer; 39using Timer=OpenSim.Region.ScriptEngine.Shared.Api.Plugins.Timer;
40using System.Reflection;
41using log4net;
40 42
41namespace OpenSim.Region.ScriptEngine.Shared.Api 43namespace OpenSim.Region.ScriptEngine.Shared.Api
42{ 44{
@@ -45,15 +47,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
45 /// </summary> 47 /// </summary>
46 public class AsyncCommandManager 48 public class AsyncCommandManager
47 { 49 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51
48 private static Thread cmdHandlerThread; 52 private static Thread cmdHandlerThread;
49 private static int cmdHandlerThreadCycleSleepms; 53 private static int cmdHandlerThreadCycleSleepms;
50 54
51 private static List<IScene> m_Scenes = new List<IScene>(); 55 /// <summary>
56 /// Lock for reading/writing static components of AsyncCommandManager.
57 /// </summary>
58 /// <remarks>
59 /// This lock exists so that multiple threads from different engines and/or different copies of the same engine
60 /// are prevented from running non-thread safe code (e.g. read/write of lists) concurrently.
61 /// </remarks>
62 private static object staticLock = new object();
63
52 private static List<IScriptEngine> m_ScriptEngines = 64 private static List<IScriptEngine> m_ScriptEngines =
53 new List<IScriptEngine>(); 65 new List<IScriptEngine>();
54 66
55 public IScriptEngine m_ScriptEngine; 67 public IScriptEngine m_ScriptEngine;
56 private IScene m_Scene;
57 68
58 private static Dictionary<IScriptEngine, Dataserver> m_Dataserver = 69 private static Dictionary<IScriptEngine, Dataserver> m_Dataserver =
59 new Dictionary<IScriptEngine, Dataserver>(); 70 new Dictionary<IScriptEngine, Dataserver>();
@@ -70,67 +81,99 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
70 81
71 public Dataserver DataserverPlugin 82 public Dataserver DataserverPlugin
72 { 83 {
73 get { return m_Dataserver[m_ScriptEngine]; } 84 get
85 {
86 lock (staticLock)
87 return m_Dataserver[m_ScriptEngine];
88 }
74 } 89 }
75 90
76 public Timer TimerPlugin 91 public Timer TimerPlugin
77 { 92 {
78 get { return m_Timer[m_ScriptEngine]; } 93 get
94 {
95 lock (staticLock)
96 return m_Timer[m_ScriptEngine];
97 }
79 } 98 }
80 99
81 public HttpRequest HttpRequestPlugin 100 public HttpRequest HttpRequestPlugin
82 { 101 {
83 get { return m_HttpRequest[m_ScriptEngine]; } 102 get
103 {
104 lock (staticLock)
105 return m_HttpRequest[m_ScriptEngine];
106 }
84 } 107 }
85 108
86 public Listener ListenerPlugin 109 public Listener ListenerPlugin
87 { 110 {
88 get { return m_Listener[m_ScriptEngine]; } 111 get
112 {
113 lock (staticLock)
114 return m_Listener[m_ScriptEngine];
115 }
89 } 116 }
90 117
91 public SensorRepeat SensorRepeatPlugin 118 public SensorRepeat SensorRepeatPlugin
92 { 119 {
93 get { return m_SensorRepeat[m_ScriptEngine]; } 120 get
121 {
122 lock (staticLock)
123 return m_SensorRepeat[m_ScriptEngine];
124 }
94 } 125 }
95 126
96 public XmlRequest XmlRequestPlugin 127 public XmlRequest XmlRequestPlugin
97 { 128 {
98 get { return m_XmlRequest[m_ScriptEngine]; } 129 get
130 {
131 lock (staticLock)
132 return m_XmlRequest[m_ScriptEngine];
133 }
99 } 134 }
100 135
101 public IScriptEngine[] ScriptEngines 136 public IScriptEngine[] ScriptEngines
102 { 137 {
103 get { return m_ScriptEngines.ToArray(); } 138 get
139 {
140 lock (staticLock)
141 return m_ScriptEngines.ToArray();
142 }
104 } 143 }
105 144
106 public AsyncCommandManager(IScriptEngine _ScriptEngine) 145 public AsyncCommandManager(IScriptEngine _ScriptEngine)
107 { 146 {
108 m_ScriptEngine = _ScriptEngine; 147 m_ScriptEngine = _ScriptEngine;
109 m_Scene = m_ScriptEngine.World; 148
110 149 // If there is more than one scene in the simulator or multiple script engines are used on the same region
111 if (m_Scenes.Count == 0) 150 // then more than one thread could arrive at this block of code simultaneously. However, it cannot be
112 ReadConfig(); 151 // executed concurrently both because concurrent list operations are not thread-safe and because of other
113 152 // race conditions such as the later check of cmdHandlerThread == null.
114 if (!m_Scenes.Contains(m_Scene)) 153 lock (staticLock)
115 m_Scenes.Add(m_Scene); 154 {
116 if (!m_ScriptEngines.Contains(m_ScriptEngine)) 155 if (m_ScriptEngines.Count == 0)
117 m_ScriptEngines.Add(m_ScriptEngine); 156 ReadConfig();
118 157
119 // Create instances of all plugins 158 if (!m_ScriptEngines.Contains(m_ScriptEngine))
120 if (!m_Dataserver.ContainsKey(m_ScriptEngine)) 159 m_ScriptEngines.Add(m_ScriptEngine);
121 m_Dataserver[m_ScriptEngine] = new Dataserver(this); 160
122 if (!m_Timer.ContainsKey(m_ScriptEngine)) 161 // Create instances of all plugins
123 m_Timer[m_ScriptEngine] = new Timer(this); 162 if (!m_Dataserver.ContainsKey(m_ScriptEngine))
124 if (!m_HttpRequest.ContainsKey(m_ScriptEngine)) 163 m_Dataserver[m_ScriptEngine] = new Dataserver(this);
125 m_HttpRequest[m_ScriptEngine] = new HttpRequest(this); 164 if (!m_Timer.ContainsKey(m_ScriptEngine))
126 if (!m_Listener.ContainsKey(m_ScriptEngine)) 165 m_Timer[m_ScriptEngine] = new Timer(this);
127 m_Listener[m_ScriptEngine] = new Listener(this); 166 if (!m_HttpRequest.ContainsKey(m_ScriptEngine))
128 if (!m_SensorRepeat.ContainsKey(m_ScriptEngine)) 167 m_HttpRequest[m_ScriptEngine] = new HttpRequest(this);
129 m_SensorRepeat[m_ScriptEngine] = new SensorRepeat(this); 168 if (!m_Listener.ContainsKey(m_ScriptEngine))
130 if (!m_XmlRequest.ContainsKey(m_ScriptEngine)) 169 m_Listener[m_ScriptEngine] = new Listener(this);
131 m_XmlRequest[m_ScriptEngine] = new XmlRequest(this); 170 if (!m_SensorRepeat.ContainsKey(m_ScriptEngine))
132 171 m_SensorRepeat[m_ScriptEngine] = new SensorRepeat(this);
133 StartThread(); 172 if (!m_XmlRequest.ContainsKey(m_ScriptEngine))
173 m_XmlRequest[m_ScriptEngine] = new XmlRequest(this);
174
175 StartThread();
176 }
134 } 177 }
135 178
136 private static void StartThread() 179 private static void StartThread()
@@ -179,42 +222,43 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
179 { 222 {
180 try 223 try
181 { 224 {
182 while (true) 225 Thread.Sleep(cmdHandlerThreadCycleSleepms);
183 {
184 Thread.Sleep(cmdHandlerThreadCycleSleepms);
185 226
186 DoOneCmdHandlerPass(); 227 DoOneCmdHandlerPass();
187 228
188 Watchdog.UpdateThread(); 229 Watchdog.UpdateThread();
189 }
190 } 230 }
191 catch 231 catch (Exception e)
192 { 232 {
233 m_log.Error("[ASYNC COMMAND MANAGER]: Exception in command handler pass: ", e);
193 } 234 }
194 } 235 }
195 } 236 }
196 237
197 private static void DoOneCmdHandlerPass() 238 private static void DoOneCmdHandlerPass()
198 { 239 {
199 // Check HttpRequests 240 lock (staticLock)
200 m_HttpRequest[m_ScriptEngines[0]].CheckHttpRequests(); 241 {
242 // Check HttpRequests
243 m_HttpRequest[m_ScriptEngines[0]].CheckHttpRequests();
201 244
202 // Check XMLRPCRequests 245 // Check XMLRPCRequests
203 m_XmlRequest[m_ScriptEngines[0]].CheckXMLRPCRequests(); 246 m_XmlRequest[m_ScriptEngines[0]].CheckXMLRPCRequests();
204 247
205 foreach (IScriptEngine s in m_ScriptEngines) 248 foreach (IScriptEngine s in m_ScriptEngines)
206 { 249 {
207 // Check Listeners 250 // Check Listeners
208 m_Listener[s].CheckListeners(); 251 m_Listener[s].CheckListeners();
209 252
210 // Check timers 253 // Check timers
211 m_Timer[s].CheckTimerEvents(); 254 m_Timer[s].CheckTimerEvents();
212 255
213 // Check Sensors 256 // Check Sensors
214 m_SensorRepeat[s].CheckSenseRepeaterEvents(); 257 m_SensorRepeat[s].CheckSenseRepeaterEvents();
215 258
216 // Check dataserver 259 // Check dataserver
217 m_Dataserver[s].ExpireRequests(); 260 m_Dataserver[s].ExpireRequests();
261 }
218 } 262 }
219 } 263 }
220 264
@@ -226,31 +270,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
226 public static void RemoveScript(IScriptEngine engine, uint localID, UUID itemID) 270 public static void RemoveScript(IScriptEngine engine, uint localID, UUID itemID)
227 { 271 {
228 // Remove a specific script 272 // Remove a specific script
273// m_log.DebugFormat("[ASYNC COMMAND MANAGER]: Removing facilities for script {0}", itemID);
229 274
230 // Remove dataserver events 275 lock (staticLock)
231 m_Dataserver[engine].RemoveEvents(localID, itemID); 276 {
277 // Remove dataserver events
278 m_Dataserver[engine].RemoveEvents(localID, itemID);
232 279
233 // Remove from: Timers 280 // Remove from: Timers
234 m_Timer[engine].UnSetTimerEvents(localID, itemID); 281 m_Timer[engine].UnSetTimerEvents(localID, itemID);
235 282
236 // Remove from: HttpRequest 283 // Remove from: HttpRequest
237 IHttpRequestModule iHttpReq = engine.World.RequestModuleInterface<IHttpRequestModule>(); 284 IHttpRequestModule iHttpReq = engine.World.RequestModuleInterface<IHttpRequestModule>();
238 if (iHttpReq != null) 285 if (iHttpReq != null)
239 iHttpReq.StopHttpRequest(localID, itemID); 286 iHttpReq.StopHttpRequest(localID, itemID);
240 287
241 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>(); 288 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
242 if (comms != null) 289 if (comms != null)
243 comms.DeleteListener(itemID); 290 comms.DeleteListener(itemID);
244 291
245 IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>(); 292 IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>();
246 if (xmlrpc != null) 293 if (xmlrpc != null)
247 { 294 {
248 xmlrpc.DeleteChannels(itemID); 295 xmlrpc.DeleteChannels(itemID);
249 xmlrpc.CancelSRDRequests(itemID); 296 xmlrpc.CancelSRDRequests(itemID);
250 } 297 }
251 298
252 // Remove Sensors 299 // Remove Sensors
253 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID); 300 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
301 }
254 } 302 }
255 303
256 /// <summary> 304 /// <summary>
@@ -260,10 +308,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
260 /// <returns></returns> 308 /// <returns></returns>
261 public static SensorRepeat GetSensorRepeatPlugin(IScriptEngine engine) 309 public static SensorRepeat GetSensorRepeatPlugin(IScriptEngine engine)
262 { 310 {
263 if (m_SensorRepeat.ContainsKey(engine)) 311 lock (staticLock)
264 return m_SensorRepeat[engine]; 312 {
265 else 313 if (m_SensorRepeat.ContainsKey(engine))
266 return null; 314 return m_SensorRepeat[engine];
315 else
316 return null;
317 }
267 } 318 }
268 319
269 /// <summary> 320 /// <summary>
@@ -273,10 +324,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
273 /// <returns></returns> 324 /// <returns></returns>
274 public static Dataserver GetDataserverPlugin(IScriptEngine engine) 325 public static Dataserver GetDataserverPlugin(IScriptEngine engine)
275 { 326 {
276 if (m_Dataserver.ContainsKey(engine)) 327 lock (staticLock)
277 return m_Dataserver[engine]; 328 {
278 else 329 if (m_Dataserver.ContainsKey(engine))
279 return null; 330 return m_Dataserver[engine];
331 else
332 return null;
333 }
280 } 334 }
281 335
282 /// <summary> 336 /// <summary>
@@ -286,10 +340,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
286 /// <returns></returns> 340 /// <returns></returns>
287 public static Timer GetTimerPlugin(IScriptEngine engine) 341 public static Timer GetTimerPlugin(IScriptEngine engine)
288 { 342 {
289 if (m_Timer.ContainsKey(engine)) 343 lock (staticLock)
290 return m_Timer[engine]; 344 {
291 else 345 if (m_Timer.ContainsKey(engine))
292 return null; 346 return m_Timer[engine];
347 else
348 return null;
349 }
293 } 350 }
294 351
295 /// <summary> 352 /// <summary>
@@ -299,10 +356,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
299 /// <returns></returns> 356 /// <returns></returns>
300 public static Listener GetListenerPlugin(IScriptEngine engine) 357 public static Listener GetListenerPlugin(IScriptEngine engine)
301 { 358 {
302 if (m_Listener.ContainsKey(engine)) 359 lock (staticLock)
303 return m_Listener[engine]; 360 {
304 else 361 if (m_Listener.ContainsKey(engine))
305 return null; 362 return m_Listener[engine];
363 else
364 return null;
365 }
306 } 366 }
307 367
308 public static void StateChange(IScriptEngine engine, uint localID, UUID itemID) 368 public static void StateChange(IScriptEngine engine, uint localID, UUID itemID)
@@ -332,28 +392,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
332 { 392 {
333 List<Object> data = new List<Object>(); 393 List<Object> data = new List<Object>();
334 394
335 Object[] listeners = m_Listener[engine].GetSerializationData(itemID); 395 lock (staticLock)
336 if (listeners.Length > 0)
337 { 396 {
338 data.Add("listener"); 397 Object[] listeners = m_Listener[engine].GetSerializationData(itemID);
339 data.Add(listeners.Length); 398 if (listeners.Length > 0)
340 data.AddRange(listeners); 399 {
341 } 400 data.Add("listener");
401 data.Add(listeners.Length);
402 data.AddRange(listeners);
403 }
342 404
343 Object[] timers=m_Timer[engine].GetSerializationData(itemID); 405 Object[] timers=m_Timer[engine].GetSerializationData(itemID);
344 if (timers.Length > 0) 406 if (timers.Length > 0)
345 { 407 {
346 data.Add("timer"); 408 data.Add("timer");
347 data.Add(timers.Length); 409 data.Add(timers.Length);
348 data.AddRange(timers); 410 data.AddRange(timers);
349 } 411 }
350 412
351 Object[] sensors = m_SensorRepeat[engine].GetSerializationData(itemID); 413 Object[] sensors = m_SensorRepeat[engine].GetSerializationData(itemID);
352 if (sensors.Length > 0) 414 if (sensors.Length > 0)
353 { 415 {
354 data.Add("sensor"); 416 data.Add("sensor");
355 data.Add(sensors.Length); 417 data.Add(sensors.Length);
356 data.AddRange(sensors); 418 data.AddRange(sensors);
419 }
357 } 420 }
358 421
359 return data.ToArray(); 422 return data.ToArray();
@@ -378,41 +441,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
378 441
379 idx+=len; 442 idx+=len;
380 443
444 lock (staticLock)
445 {
381 switch (type) 446 switch (type)
382 { 447 {
383 case "listener": 448 case "listener":
384 m_Listener[engine].CreateFromData(localID, itemID, 449 m_Listener[engine].CreateFromData(localID, itemID,
385 hostID, item); 450 hostID, item);
386 break; 451 break;
387 case "timer": 452 case "timer":
388 m_Timer[engine].CreateFromData(localID, itemID, 453 m_Timer[engine].CreateFromData(localID, itemID,
389 hostID, item); 454 hostID, item);
390 break; 455 break;
391 case "sensor": 456 case "sensor":
392 m_SensorRepeat[engine].CreateFromData(localID, 457 m_SensorRepeat[engine].CreateFromData(localID,
393 itemID, hostID, item); 458 itemID, hostID, item);
394 break; 459 break;
460 }
395 } 461 }
396 } 462 }
397 } 463 }
398 } 464 }
399
400 #region Check llRemoteData channels
401
402 #endregion
403
404 #region Check llListeners
405
406 #endregion
407
408 /// <summary>
409 /// If set to true then threads and stuff should try to make a graceful exit
410 /// </summary>
411 public bool PleaseShutdown
412 {
413 get { return _PleaseShutdown; }
414 set { _PleaseShutdown = value; }
415 }
416 private bool _PleaseShutdown = false;
417 } 465 }
418} 466}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index e8502ac..f05aaa9 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -1664,6 +1664,75 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1664 m_host.SetFaceColorAlpha(face, color, null); 1664 m_host.SetFaceColorAlpha(face, color, null);
1665 } 1665 }
1666 1666
1667 /*
1668 public void llSetContentType(LSL_Key id, LSL_Integer type)
1669 {
1670 m_host.AddScriptLPS(1);
1671
1672 if (m_UrlModule == null)
1673 return;
1674
1675 // Make sure the content type is text/plain to start with
1676 m_UrlModule.HttpContentType(new UUID(id), "text/plain");
1677
1678 // Is the object owner online and in the region
1679 ScenePresence agent = World.GetScenePresence(m_host.ParentGroup.OwnerID);
1680 if (agent == null || agent.IsChildAgent)
1681 return; // Fail if the owner is not in the same region
1682
1683 // Is it the embeded browser?
1684 string userAgent = m_UrlModule.GetHttpHeader(new UUID(id), "user-agent");
1685 if (userAgent.IndexOf("SecondLife") < 0)
1686 return; // Not the embedded browser. Is this check good enough?
1687
1688 // Use the IP address of the client and check against the request
1689 // seperate logins from the same IP will allow all of them to get non-text/plain as long
1690 // as the owner is in the region. Same as SL!
1691 string logonFromIPAddress = agent.ControllingClient.RemoteEndPoint.Address.ToString();
1692 string requestFromIPAddress = m_UrlModule.GetHttpHeader(new UUID(id), "remote_addr");
1693 //m_log.Debug("IP from header='" + requestFromIPAddress + "' IP from endpoint='" + logonFromIPAddress + "'");
1694 if (requestFromIPAddress == null || requestFromIPAddress.Trim() == "")
1695 return;
1696 if (logonFromIPAddress == null || logonFromIPAddress.Trim() == "")
1697 return;
1698
1699 // If the request isnt from the same IP address then the request cannot be from the owner
1700 if (!requestFromIPAddress.Trim().Equals(logonFromIPAddress.Trim()))
1701 return;
1702
1703 switch (type)
1704 {
1705 case ScriptBaseClass.CONTENT_TYPE_HTML:
1706 m_UrlModule.HttpContentType(new UUID(id), "text/html");
1707 break;
1708 case ScriptBaseClass.CONTENT_TYPE_XML:
1709 m_UrlModule.HttpContentType(new UUID(id), "application/xml");
1710 break;
1711 case ScriptBaseClass.CONTENT_TYPE_XHTML:
1712 m_UrlModule.HttpContentType(new UUID(id), "application/xhtml+xml");
1713 break;
1714 case ScriptBaseClass.CONTENT_TYPE_ATOM:
1715 m_UrlModule.HttpContentType(new UUID(id), "application/atom+xml");
1716 break;
1717 case ScriptBaseClass.CONTENT_TYPE_JSON:
1718 m_UrlModule.HttpContentType(new UUID(id), "application/json");
1719 break;
1720 case ScriptBaseClass.CONTENT_TYPE_LLSD:
1721 m_UrlModule.HttpContentType(new UUID(id), "application/llsd+xml");
1722 break;
1723 case ScriptBaseClass.CONTENT_TYPE_FORM:
1724 m_UrlModule.HttpContentType(new UUID(id), "application/x-www-form-urlencoded");
1725 break;
1726 case ScriptBaseClass.CONTENT_TYPE_RSS:
1727 m_UrlModule.HttpContentType(new UUID(id), "application/rss+xml");
1728 break;
1729 default:
1730 m_UrlModule.HttpContentType(new UUID(id), "text/plain");
1731 break;
1732 }
1733 }
1734 */
1735
1667 public void SetTexGen(SceneObjectPart part, int face,int style) 1736 public void SetTexGen(SceneObjectPart part, int face,int style)
1668 { 1737 {
1669 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 1738 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
@@ -2772,9 +2841,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2772 // send the sound, once, to all clients in range 2841 // send the sound, once, to all clients in range
2773 if (m_SoundModule != null) 2842 if (m_SoundModule != null)
2774 { 2843 {
2775 m_SoundModule.SendSound(m_host.UUID, 2844 m_SoundModule.SendSound(
2776 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume, false, 0, 2845 m_host.UUID,
2777 0, false, false); 2846 ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound),
2847 volume, false, m_host.SoundQueueing ? (byte)SoundFlags.Queue : (byte)SoundFlags.None,
2848 0, false, false);
2778 } 2849 }
2779 } 2850 }
2780 2851
@@ -5108,6 +5179,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5108 5179
5109 s = Math.Cos(angle * 0.5); 5180 s = Math.Cos(angle * 0.5);
5110 t = Math.Sin(angle * 0.5); // temp value to avoid 2 more sin() calcs 5181 t = Math.Sin(angle * 0.5); // temp value to avoid 2 more sin() calcs
5182 axis = LSL_Vector.Norm(axis);
5111 x = axis.x * t; 5183 x = axis.x * t;
5112 y = axis.y * t; 5184 y = axis.y * t;
5113 z = axis.z * t; 5185 z = axis.z * t;
@@ -5115,41 +5187,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5115 return new LSL_Rotation(x,y,z,s); 5187 return new LSL_Rotation(x,y,z,s);
5116 } 5188 }
5117 5189
5118 5190 /// <summary>
5119 // Xantor 29/apr/2008 5191 /// Returns the axis of rotation for a quaternion
5120 // converts a Quaternion to X,Y,Z axis rotations 5192 /// </summary>
5193 /// <returns></returns>
5194 /// <param name='rot'></param>
5121 public LSL_Vector llRot2Axis(LSL_Rotation rot) 5195 public LSL_Vector llRot2Axis(LSL_Rotation rot)
5122 { 5196 {
5123 m_host.AddScriptLPS(1); 5197 m_host.AddScriptLPS(1);
5124 double x,y,z;
5125 5198
5126 if (rot.s > 1) // normalization needed 5199 if (Math.Abs(rot.s) > 1) // normalization needed
5127 { 5200 rot.Normalize();
5128 double length = Math.Sqrt(rot.x * rot.x + rot.y * rot.y +
5129 rot.z * rot.z + rot.s * rot.s);
5130
5131 rot.x /= length;
5132 rot.y /= length;
5133 rot.z /= length;
5134 rot.s /= length;
5135 5201
5136 }
5137
5138 // double angle = 2 * Math.Acos(rot.s);
5139 double s = Math.Sqrt(1 - rot.s * rot.s); 5202 double s = Math.Sqrt(1 - rot.s * rot.s);
5140 if (s < 0.001) 5203 if (s < 0.001)
5141 { 5204 {
5142 x = 1; 5205 return new LSL_Vector(1, 0, 0);
5143 y = z = 0;
5144 } 5206 }
5145 else 5207 else
5146 { 5208 {
5147 x = rot.x / s; // normalise axis 5209 double invS = 1.0 / s;
5148 y = rot.y / s; 5210 if (rot.s < 0) invS = -invS;
5149 z = rot.z / s; 5211 return new LSL_Vector(rot.x * invS, rot.y * invS, rot.z * invS);
5150 } 5212 }
5151
5152 return new LSL_Vector(x,y,z);
5153 } 5213 }
5154 5214
5155 5215
@@ -5158,18 +5218,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5158 { 5218 {
5159 m_host.AddScriptLPS(1); 5219 m_host.AddScriptLPS(1);
5160 5220
5161 if (rot.s > 1) // normalization needed 5221 if (Math.Abs(rot.s) > 1) // normalization needed
5162 { 5222 rot.Normalize();
5163 double length = Math.Sqrt(rot.x * rot.x + rot.y * rot.y +
5164 rot.z * rot.z + rot.s * rot.s);
5165
5166 rot.x /= length;
5167 rot.y /= length;
5168 rot.z /= length;
5169 rot.s /= length;
5170 }
5171 5223
5172 double angle = 2 * Math.Acos(rot.s); 5224 double angle = 2 * Math.Acos(rot.s);
5225 if (angle > Math.PI)
5226 angle = 2 * Math.PI - angle;
5173 5227
5174 return angle; 5228 return angle;
5175 } 5229 }
@@ -8255,7 +8309,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8255 return null; 8309 return null;
8256 8310
8257 string ph = rules.Data[idx++].ToString(); 8311 string ph = rules.Data[idx++].ToString();
8258 parentgrp.ScriptSetPhantomStatus(ph.Equals("1")); 8312 part.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1"));
8259 8313
8260 break; 8314 break;
8261 8315
@@ -8308,7 +8362,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8308 return null; 8362 return null;
8309 string temp = rules.Data[idx++].ToString(); 8363 string temp = rules.Data[idx++].ToString();
8310 8364
8311 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1")); 8365 part.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1"));
8312 8366
8313 break; 8367 break;
8314 8368
@@ -12673,6 +12727,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12673 public void llSetSoundQueueing(int queue) 12727 public void llSetSoundQueueing(int queue)
12674 { 12728 {
12675 m_host.AddScriptLPS(1); 12729 m_host.AddScriptLPS(1);
12730
12731 if (m_SoundModule != null)
12732 m_SoundModule.SetSoundQueueing(m_host.UUID, queue == ScriptBaseClass.TRUE.value);
12676 } 12733 }
12677 12734
12678 public void llCollisionSprite(string impact_sprite) 12735 public void llCollisionSprite(string impact_sprite)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index daf89e5..2260ec8 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -340,6 +340,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
340 void llSetCameraParams(LSL_List rules); 340 void llSetCameraParams(LSL_List rules);
341 void llSetClickAction(int action); 341 void llSetClickAction(int action);
342 void llSetColor(LSL_Vector color, int face); 342 void llSetColor(LSL_Vector color, int face);
343 void llSetContentType(LSL_Key id, LSL_Integer type);
343 void llSetDamage(double damage); 344 void llSetDamage(double damage);
344 void llSetForce(LSL_Vector force, int local); 345 void llSetForce(LSL_Vector force, int local);
345 void llSetForceAndTorque(LSL_Vector force, LSL_Vector torque, int local); 346 void llSetForceAndTorque(LSL_Vector force, LSL_Vector torque, int local);
@@ -434,6 +435,5 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
434 void llSetKeyframedMotion(LSL_List frames, LSL_List options); 435 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
435 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 436 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
436 LSL_List llGetPhysicsMaterial(); 437 LSL_List llGetPhysicsMaterial();
437 void llSetContentType(LSL_Key id, LSL_Integer content_type);
438 } 438 }
439} 439}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index 6efa73f..15b21ac 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -361,6 +361,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
361 public const int HTTP_CUSTOM_HEADER = 5; 361 public const int HTTP_CUSTOM_HEADER = 5;
362 public const int HTTP_PRAGMA_NO_CACHE = 6; 362 public const int HTTP_PRAGMA_NO_CACHE = 6;
363 363
364 // llSetContentType
365 public const int CONTENT_TYPE_TEXT = 0; //text/plain
366 public const int CONTENT_TYPE_HTML = 1; //text/html
367 public const int CONTENT_TYPE_XML = 2; //application/xml
368 public const int CONTENT_TYPE_XHTML = 3; //application/xhtml+xml
369 public const int CONTENT_TYPE_ATOM = 4; //application/atom+xml
370 public const int CONTENT_TYPE_JSON = 5; //application/json
371 public const int CONTENT_TYPE_LLSD = 6; //application/llsd+xml
372 public const int CONTENT_TYPE_FORM = 7; //application/x-www-form-urlencoded
373 public const int CONTENT_TYPE_RSS = 8; //application/rss+xml
374
364 public const int PRIM_MATERIAL = 2; 375 public const int PRIM_MATERIAL = 2;
365 public const int PRIM_PHYSICS = 3; 376 public const int PRIM_PHYSICS = 3;
366 public const int PRIM_TEMP_ON_REZ = 4; 377 public const int PRIM_TEMP_ON_REZ = 4;
@@ -772,8 +783,5 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
772 /// process message parameter as regex 783 /// process message parameter as regex
773 /// </summary> 784 /// </summary>
774 public const int OS_LISTEN_REGEX_MESSAGE = 0x2; 785 public const int OS_LISTEN_REGEX_MESSAGE = 0x2;
775
776 public const int CONTENT_TYPE_TEXT = 0;
777 public const int CONTENT_TYPE_HTML = 1;
778 } 786 }
779} 787}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 6f3677c..b58686b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -1535,6 +1535,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1535 m_LSL_Functions.llSetColor(color, face); 1535 m_LSL_Functions.llSetColor(color, face);
1536 } 1536 }
1537 1537
1538 public void llSetContentType(LSL_Key id, LSL_Integer type)
1539 {
1540 m_LSL_Functions.llSetContentType(id, type);
1541 }
1542
1538 public void llSetDamage(double damage) 1543 public void llSetDamage(double damage)
1539 { 1544 {
1540 m_LSL_Functions.llSetDamage(damage); 1545 m_LSL_Functions.llSetDamage(damage);
@@ -2014,10 +2019,5 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
2014 { 2019 {
2015 return m_LSL_Functions.llGetPhysicsMaterial(); 2020 return m_LSL_Functions.llGetPhysicsMaterial();
2016 } 2021 }
2017
2018 public void llSetContentType(LSL_Key id, LSL_Integer content_type)
2019 {
2020 m_LSL_Functions.llSetContentType(id, content_type);
2021 }
2022 } 2022 }
2023} 2023}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 26850c4..8da06d1 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -528,8 +528,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
528 { 528 {
529 File.Delete(savedState); 529 File.Delete(savedState);
530 } 530 }
531 catch(Exception) 531 catch (Exception e)
532 { 532 {
533 m_log.Warn(
534 string.Format(
535 "[SCRIPT INSTANCE]: Could not delete script state {0} for script {1} (id {2}) in part {3} (id {4}) in object {5} in {6}. Exception ",
536 ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name),
537 e);
533 } 538 }
534 } 539 }
535 540
@@ -567,9 +572,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
567 572
568 public bool Stop(int timeout) 573 public bool Stop(int timeout)
569 { 574 {
570// m_log.DebugFormat( 575 if (DebugLevel >= 1)
571// "[SCRIPT INSTANCE]: Stopping script {0} {1} in {2} {3} with timeout {4} {5} {6}", 576 m_log.DebugFormat(
572// ScriptName, ItemID, PrimName, ObjectID, timeout, m_InSelfDelete, DateTime.Now.Ticks); 577 "[SCRIPT INSTANCE]: Stopping script {0} {1} in {2} {3} with timeout {4} {5} {6}",
578 ScriptName, ItemID, PrimName, ObjectID, timeout, m_InSelfDelete, DateTime.Now.Ticks);
573 579
574 IScriptWorkItem workItem; 580 IScriptWorkItem workItem;
575 581
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index b524a18..4ba0e64 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -371,6 +371,31 @@ namespace OpenSim.Region.ScriptEngine.Shared
371 371
372 #endregion 372 #endregion
373 373
374 #region Methods
375 public Quaternion Normalize()
376 {
377 double length = Math.Sqrt(x * x + y * y + z * z + s * s);
378 if (length < float.Epsilon)
379 {
380 x = 0;
381 y = 0;
382 z = 0;
383 s = 1;
384 }
385 else
386 {
387
388 double invLength = 1.0 / length;
389 x *= invLength;
390 y *= invLength;
391 z *= invLength;
392 s *= invLength;
393 }
394
395 return this;
396 }
397 #endregion
398
374 #region Overriders 399 #region Overriders
375 400
376 public override int GetHashCode() 401 public override int GetHashCode()
@@ -546,21 +571,33 @@ namespace OpenSim.Region.ScriptEngine.Shared
546 571
547 set {m_data = value; } 572 set {m_data = value; }
548 } 573 }
549 // Function to obtain LSL type from an index. This is needed 574
550 // because LSL lists allow for multiple types, and safely 575 /// <summary>
551 // iterating in them requires a type check. 576 /// Obtain LSL type from an index.
577 /// </summary>
578 /// <remarks>
579 /// This is needed because LSL lists allow for multiple types, and safely
580 /// iterating in them requires a type check.
581 /// </remarks>
582 /// <returns></returns>
583 /// <param name='itemIndex'></param>
552 public Type GetLSLListItemType(int itemIndex) 584 public Type GetLSLListItemType(int itemIndex)
553 { 585 {
554 return m_data[itemIndex].GetType(); 586 return m_data[itemIndex].GetType();
555 } 587 }
556 588
557 // Member functions to obtain item as specific types. 589 /// <summary>
558 // For cases where implicit conversions would apply if items 590 /// Obtain float from an index.
559 // were not in a list (e.g. integer to float, but not float 591 /// </summary>
560 // to integer) functions check for alternate types so as to 592 /// <remarks>
561 // down-cast from Object to the correct type. 593 /// For cases where implicit conversions would apply if items
562 // Note: no checks for item index being valid are performed 594 /// were not in a list (e.g. integer to float, but not float
563 595 /// to integer) functions check for alternate types so as to
596 /// down-cast from Object to the correct type.
597 /// Note: no checks for item index being valid are performed
598 /// </remarks>
599 /// <returns></returns>
600 /// <param name='itemIndex'></param>
564 public LSL_Types.LSLFloat GetLSLFloatItem(int itemIndex) 601 public LSL_Types.LSLFloat GetLSLFloatItem(int itemIndex)
565 { 602 {
566 if (m_data[itemIndex] is LSL_Types.LSLInteger) 603 if (m_data[itemIndex] is LSL_Types.LSLInteger)
@@ -591,26 +628,14 @@ namespace OpenSim.Region.ScriptEngine.Shared
591 628
592 public LSL_Types.LSLString GetLSLStringItem(int itemIndex) 629 public LSL_Types.LSLString GetLSLStringItem(int itemIndex)
593 { 630 {
594 if (m_data[itemIndex] is LSL_Types.key) 631 if (m_data[itemIndex] is LSL_Types.key)
595 { 632 {
596 return (LSL_Types.key)m_data[itemIndex]; 633 return (LSL_Types.key)m_data[itemIndex];
597 } 634 }
598 else if (m_data[itemIndex] is String) 635 else
599 { 636 {
600 return new LSL_Types.LSLString((string)m_data[itemIndex]); 637 return new LSL_Types.LSLString(m_data[itemIndex].ToString());
601 } 638 }
602 else if (m_data[itemIndex] is LSL_Types.LSLFloat)
603 {
604 return new LSL_Types.LSLString((LSLFloat)m_data[itemIndex]);
605 }
606 else if (m_data[itemIndex] is LSL_Types.LSLInteger)
607 {
608 return new LSL_Types.LSLString((LSLInteger)m_data[itemIndex]);
609 }
610 else
611 {
612 return (LSL_Types.LSLString)m_data[itemIndex];
613 }
614 } 639 }
615 640
616 public LSL_Types.LSLInteger GetLSLIntegerItem(int itemIndex) 641 public LSL_Types.LSLInteger GetLSLIntegerItem(int itemIndex)
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 17243ab..9d1e143 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -551,7 +551,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
551 /// <param name="instance"></param> 551 /// <param name="instance"></param>
552 /// <param name="keySelector">Basis on which to sort output. Can be null if no sort needs to take place</param> 552 /// <param name="keySelector">Basis on which to sort output. Can be null if no sort needs to take place</param>
553 private void HandleScriptsAction<TKey>( 553 private void HandleScriptsAction<TKey>(
554 string[] cmdparams, Action<IScriptInstance> action, Func<IScriptInstance, TKey> keySelector) 554 string[] cmdparams, Action<IScriptInstance> action, System.Func<IScriptInstance, TKey> keySelector)
555 { 555 {
556 if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_Scene)) 556 if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_Scene))
557 return; 557 return;
@@ -609,7 +609,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
609 if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_Scene)) 609 if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_Scene))
610 return; 610 return;
611 611
612 MainConsole.Instance.OutputFormat(GetStatusReport()); 612 MainConsole.Instance.Output(GetStatusReport());
613 } 613 }
614 614
615 public string GetStatusReport() 615 public string GetStatusReport()
@@ -708,7 +708,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
708 sb.AppendFormat("Containing part UUID: {0}\n", instance.ObjectID); 708 sb.AppendFormat("Containing part UUID: {0}\n", instance.ObjectID);
709 sb.AppendFormat("Position : {0}\n", sop.AbsolutePosition); 709 sb.AppendFormat("Position : {0}\n", sop.AbsolutePosition);
710 710
711 MainConsole.Instance.OutputFormat(sb.ToString()); 711 MainConsole.Instance.Output(sb.ToString());
712 } 712 }
713 713
714 private void HandleSuspendScript(IScriptInstance instance) 714 private void HandleSuspendScript(IScriptInstance instance)
@@ -1599,7 +1599,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1599 startInfo.MaxWorkerThreads = maxThreads; 1599 startInfo.MaxWorkerThreads = maxThreads;
1600 startInfo.MinWorkerThreads = minThreads; 1600 startInfo.MinWorkerThreads = minThreads;
1601 startInfo.ThreadPriority = threadPriority;; 1601 startInfo.ThreadPriority = threadPriority;;
1602 startInfo.StackSize = stackSize; 1602 startInfo.MaxStackSize = stackSize;
1603 startInfo.StartSuspended = true; 1603 startInfo.StartSuspended = true;
1604 1604
1605 m_ThreadPool = new SmartThreadPool(startInfo); 1605 m_ThreadPool = new SmartThreadPool(startInfo);
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XWorkItem.cs b/OpenSim/Region/ScriptEngine/XEngine/XWorkItem.cs
index 8dd7677..9d9dee1 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XWorkItem.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XWorkItem.cs
@@ -52,16 +52,16 @@ namespace OpenSim.Region.ScriptEngine.XEngine
52 return wr.Cancel(); 52 return wr.Cancel();
53 } 53 }
54 54
55 public void Abort() 55 public bool Abort()
56 { 56 {
57 wr.Abort(); 57 return wr.Cancel(true);
58 } 58 }
59 59
60 public bool Wait(int t) 60 public bool Wait(int t)
61 { 61 {
62 // We use the integer version of WaitAll because the current version of SmartThreadPool has a bug with the 62 // We use the integer version of WaitAll because the current version of SmartThreadPool has a bug with the
63 // TimeSpan version. The number of milliseconds in TimeSpan is an int64 so when STP casts it down to an 63 // TimeSpan version. The number of milliseconds in TimeSpan is an int64 so when STP casts it down to an
64 // int (32-bit) we can end up with bad values. This occurs on Windows though curious not on Mono 2.10.8 64 // int (32-bit) we can end up with bad values. This occurs on Windows though curiously not on Mono 2.10.8
65 // (or very likely other versions of Mono at least up until 3.0.3). 65 // (or very likely other versions of Mono at least up until 3.0.3).
66 return SmartThreadPool.WaitAll(new IWorkItemResult[] {wr}, t, false); 66 return SmartThreadPool.WaitAll(new IWorkItemResult[] {wr}, t, false);
67 } 67 }