From 903cc71f0d6b0caaf8dfa176dabaeac21e77490d Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 19 Jan 2013 22:53:51 +0100 Subject: [PATCH 01/14] Remove an extra ScriptSleep (merge artefact) from llSetLinkPrimitiveParamsFast --- .../Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 617f382242..fcb68b2896 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -7782,8 +7782,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); - - ScriptSleep(200); } private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) From 461ecd7cf9edebce45ab715901a7f3b02c216e7b Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 20 Jan 2013 02:08:38 +0100 Subject: [PATCH 02/14] Refactor scripted http request to use async calls rather than hard threads --- .../HttpRequest/ScriptsHttpRequests.cs | 140 +++++++++++------- 1 file changed, 87 insertions(+), 53 deletions(-) diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs index a0ae2030cb..5b39794783 100644 --- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs +++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs @@ -206,7 +206,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest m_pendingRequests.Add(reqID, htc); } - htc.Process(); + htc.SendRequest(); return reqID; } @@ -340,7 +340,6 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest public string HttpMIMEType = "text/plain;charset=utf-8"; public int HttpTimeout; public bool HttpVerifyCert = true; - private Thread httpThread; // Request info private UUID _itemID; @@ -374,27 +373,11 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest public void Process() { - httpThread = new Thread(SendRequest); - httpThread.Name = "HttpRequestThread"; - httpThread.Priority = ThreadPriority.BelowNormal; - httpThread.IsBackground = true; - _finished = false; - httpThread.Start(); + SendRequest(); } - /* - * TODO: More work on the response codes. Right now - * returning 200 for success or 499 for exception - */ - public void SendRequest() { - HttpWebResponse response = null; - StringBuilder sb = new StringBuilder(); - byte[] buf = new byte[8192]; - string tempString = null; - int count = 0; - try { Request = (HttpWebRequest) WebRequest.Create(Url); @@ -409,13 +392,9 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest { // We could hijack Connection Group Name to identify // a desired security exception. But at the moment we'll use a dummy header instead. -// Request.ConnectionGroupName = "NoVerify"; Request.Headers.Add("NoVerifyCert", "true"); } -// else -// { -// Request.ConnectionGroupName="Verify"; -// } + if (proxyurl != null && proxyurl.Length > 0) { if (proxyexcepts != null && proxyexcepts.Length > 0) @@ -430,10 +409,14 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest } foreach (KeyValuePair entry in ResponseHeaders) + { if (entry.Key.ToLower().Equals("user-agent")) Request.UserAgent = entry.Value; else Request.Headers[entry.Key] = entry.Value; + } + + Request.Timeout = HttpTimeout; // Encode outbound data if (OutboundBody.Length > 0) @@ -441,16 +424,78 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest byte[] data = Util.UTF8.GetBytes(OutboundBody); Request.ContentLength = data.Length; - Stream bstream = Request.GetRequestStream(); - bstream.Write(data, 0, data.Length); - bstream.Close(); + Request.BeginGetRequestStream(new AsyncCallback(SendRequestData), this); + return; } - Request.Timeout = HttpTimeout; + Request.BeginGetResponse(new AsyncCallback(ProcessResponse), this); + } + catch (Exception e) + { + // Do nothing. Abort was called. + } + } + + private void SendRequestData(IAsyncResult ar) + { + try + { + byte[] data = Util.UTF8.GetBytes(OutboundBody); + + Stream bstream = Request.EndGetRequestStream(ar); + bstream.Write(data, 0, data.Length); + bstream.Close(); + + Request.BeginGetResponse(new AsyncCallback(ProcessResponse), this); + } + catch (WebException e) + { + // Abort was called. Just go away + if (e.Status == WebExceptionStatus.RequestCanceled) + return; + + // Server errored on request + if (e.Status == WebExceptionStatus.ProtocolError && e.Response != null) + { + HttpWebResponse webRsp = (HttpWebResponse)e.Response; + + Status = (int)webRsp.StatusCode; + + try + { + using (Stream responseStream = webRsp.GetResponseStream()) + { + ResponseBody = responseStream.GetStreamString(); + } + } + catch + { + ResponseBody = webRsp.StatusDescription; + } + finally + { + webRsp.Close(); + } + return; + } + + _finished = true; + } + } + + private void ProcessResponse(IAsyncResult ar) + { + HttpWebResponse response = null; + StringBuilder sb = new StringBuilder(); + byte[] buf = new byte[8192]; + string tempString = null; + int count = 0; + + try + { try { - // execute the request - response = (HttpWebResponse) Request.GetResponse(); + response = (HttpWebResponse) Request.EndGetResponse(ar); } catch (WebException e) { @@ -485,33 +530,22 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest ResponseBody = sb.ToString().Replace("\r", ""); } - catch (Exception e) + catch (WebException e) { - if (e is WebException && ((WebException)e).Status == WebExceptionStatus.ProtocolError) - { - HttpWebResponse webRsp = (HttpWebResponse)((WebException)e).Response; - Status = (int)webRsp.StatusCode; - try - { - using (Stream responseStream = webRsp.GetResponseStream()) - { - ResponseBody = responseStream.GetStreamString(); - } - } - catch - { - ResponseBody = webRsp.StatusDescription; - } - } - else - { - Status = (int)OSHttpStatusCode.ClientErrorJoker; - ResponseBody = e.Message; - } + // Abort was called. Just go away + if (e.Status == WebExceptionStatus.RequestCanceled) + return; + Status = (int)OSHttpStatusCode.ClientErrorJoker; + + ResponseBody = e.Message; _finished = true; return; } + catch (Exception e) + { + // Ignore + } finally { if (response != null) @@ -525,7 +559,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest { try { - httpThread.Abort(); + Request.Abort(); } catch (Exception) { From cf4bf7432a545888e3af8f540f65092aea6f2686 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 20 Jan 2013 15:58:20 +0100 Subject: [PATCH 03/14] Revert "Refactor scripted http request to use async calls rather than hard threads" This reverts commit 461ecd7cf9edebce45ab715901a7f3b02c216e7b. --- .../HttpRequest/ScriptsHttpRequests.cs | 144 +++++++----------- 1 file changed, 55 insertions(+), 89 deletions(-) diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs index 5b39794783..a0ae2030cb 100644 --- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs +++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs @@ -206,7 +206,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest m_pendingRequests.Add(reqID, htc); } - htc.SendRequest(); + htc.Process(); return reqID; } @@ -340,6 +340,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest public string HttpMIMEType = "text/plain;charset=utf-8"; public int HttpTimeout; public bool HttpVerifyCert = true; + private Thread httpThread; // Request info private UUID _itemID; @@ -373,11 +374,27 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest public void Process() { - SendRequest(); + httpThread = new Thread(SendRequest); + httpThread.Name = "HttpRequestThread"; + httpThread.Priority = ThreadPriority.BelowNormal; + httpThread.IsBackground = true; + _finished = false; + httpThread.Start(); } + /* + * TODO: More work on the response codes. Right now + * returning 200 for success or 499 for exception + */ + public void SendRequest() { + HttpWebResponse response = null; + StringBuilder sb = new StringBuilder(); + byte[] buf = new byte[8192]; + string tempString = null; + int count = 0; + try { Request = (HttpWebRequest) WebRequest.Create(Url); @@ -392,9 +409,13 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest { // We could hijack Connection Group Name to identify // a desired security exception. But at the moment we'll use a dummy header instead. +// Request.ConnectionGroupName = "NoVerify"; Request.Headers.Add("NoVerifyCert", "true"); } - +// else +// { +// Request.ConnectionGroupName="Verify"; +// } if (proxyurl != null && proxyurl.Length > 0) { if (proxyexcepts != null && proxyexcepts.Length > 0) @@ -409,14 +430,10 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest } foreach (KeyValuePair entry in ResponseHeaders) - { if (entry.Key.ToLower().Equals("user-agent")) Request.UserAgent = entry.Value; else Request.Headers[entry.Key] = entry.Value; - } - - Request.Timeout = HttpTimeout; // Encode outbound data if (OutboundBody.Length > 0) @@ -424,78 +441,16 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest byte[] data = Util.UTF8.GetBytes(OutboundBody); Request.ContentLength = data.Length; - Request.BeginGetRequestStream(new AsyncCallback(SendRequestData), this); - return; + Stream bstream = Request.GetRequestStream(); + bstream.Write(data, 0, data.Length); + bstream.Close(); } - Request.BeginGetResponse(new AsyncCallback(ProcessResponse), this); - } - catch (Exception e) - { - // Do nothing. Abort was called. - } - } - - private void SendRequestData(IAsyncResult ar) - { - try - { - byte[] data = Util.UTF8.GetBytes(OutboundBody); - - Stream bstream = Request.EndGetRequestStream(ar); - bstream.Write(data, 0, data.Length); - bstream.Close(); - - Request.BeginGetResponse(new AsyncCallback(ProcessResponse), this); - } - catch (WebException e) - { - // Abort was called. Just go away - if (e.Status == WebExceptionStatus.RequestCanceled) - return; - - // Server errored on request - if (e.Status == WebExceptionStatus.ProtocolError && e.Response != null) - { - HttpWebResponse webRsp = (HttpWebResponse)e.Response; - - Status = (int)webRsp.StatusCode; - - try - { - using (Stream responseStream = webRsp.GetResponseStream()) - { - ResponseBody = responseStream.GetStreamString(); - } - } - catch - { - ResponseBody = webRsp.StatusDescription; - } - finally - { - webRsp.Close(); - } - return; - } - - _finished = true; - } - } - - private void ProcessResponse(IAsyncResult ar) - { - HttpWebResponse response = null; - StringBuilder sb = new StringBuilder(); - byte[] buf = new byte[8192]; - string tempString = null; - int count = 0; - - try - { + Request.Timeout = HttpTimeout; try { - response = (HttpWebResponse) Request.EndGetResponse(ar); + // execute the request + response = (HttpWebResponse) Request.GetResponse(); } catch (WebException e) { @@ -530,21 +485,32 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest ResponseBody = sb.ToString().Replace("\r", ""); } - catch (WebException e) - { - // Abort was called. Just go away - if (e.Status == WebExceptionStatus.RequestCanceled) - return; - - Status = (int)OSHttpStatusCode.ClientErrorJoker; - - ResponseBody = e.Message; - _finished = true; - return; - } catch (Exception e) { - // Ignore + if (e is WebException && ((WebException)e).Status == WebExceptionStatus.ProtocolError) + { + HttpWebResponse webRsp = (HttpWebResponse)((WebException)e).Response; + Status = (int)webRsp.StatusCode; + try + { + using (Stream responseStream = webRsp.GetResponseStream()) + { + ResponseBody = responseStream.GetStreamString(); + } + } + catch + { + ResponseBody = webRsp.StatusDescription; + } + } + else + { + Status = (int)OSHttpStatusCode.ClientErrorJoker; + ResponseBody = e.Message; + } + + _finished = true; + return; } finally { @@ -559,7 +525,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest { try { - Request.Abort(); + httpThread.Abort(); } catch (Exception) { From b7b3063849c8d7299fa0c262e122ff1a050bfdcb Mon Sep 17 00:00:00 2001 From: Melanie Date: Sun, 20 Jan 2013 18:38:00 +0100 Subject: [PATCH 04/14] Implement HTTP Request froma thread pool to avoid packet congestion --- .../HttpRequest/ScriptsHttpRequests.cs | 59 ++++++++++++++----- prebuild.xml | 1 + 2 files changed, 46 insertions(+), 14 deletions(-) diff --git a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs index a0ae2030cb..708b99d6ea 100644 --- a/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs +++ b/OpenSim/Region/CoreModules/Scripting/HttpRequest/ScriptsHttpRequests.cs @@ -42,6 +42,7 @@ using OpenSim.Framework.Servers.HttpServer; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using Mono.Addins; +using Amib.Threading; /***************************************************** * @@ -102,6 +103,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest private Dictionary m_pendingRequests; private Scene m_scene; // private Queue rpcQueue = new Queue(); + public static SmartThreadPool ThreadPool = null; public HttpRequestModule() { @@ -279,7 +281,30 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest m_proxyurl = config.Configs["Startup"].GetString("HttpProxy"); m_proxyexcepts = config.Configs["Startup"].GetString("HttpProxyExceptions"); + int maxThreads = 50; + + IConfig httpConfig = config.Configs["HttpRequestModule"]; + if (httpConfig != null) + { + maxThreads = httpConfig.GetInt("MaxPoolThreads", maxThreads); + } + m_pendingRequests = new Dictionary(); + + // First instance sets this up for all sims + if (ThreadPool == null) + { + STPStartInfo startInfo = new STPStartInfo(); + startInfo.IdleTimeout = 20000; + startInfo.MaxWorkerThreads = maxThreads; + startInfo.MinWorkerThreads = 5; + startInfo.ThreadPriority = ThreadPriority.BelowNormal; + startInfo.StartSuspended = true; + + ThreadPool = new SmartThreadPool(startInfo); + + ThreadPool.Start(); + } } public void AddRegion(Scene scene) @@ -340,7 +365,7 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest public string HttpMIMEType = "text/plain;charset=utf-8"; public int HttpTimeout; public bool HttpVerifyCert = true; - private Thread httpThread; + public IWorkItemResult WorkItem = null; // Request info private UUID _itemID; @@ -374,12 +399,16 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest public void Process() { - httpThread = new Thread(SendRequest); - httpThread.Name = "HttpRequestThread"; - httpThread.Priority = ThreadPriority.BelowNormal; - httpThread.IsBackground = true; _finished = false; - httpThread.Start(); + + lock (HttpRequestModule.ThreadPool) + WorkItem = HttpRequestModule.ThreadPool.QueueWorkItem(new WorkItemCallback(StpSendWrapper), null); + } + + private object StpSendWrapper(object o) + { + SendRequest(); + return null; } /* @@ -409,13 +438,8 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest { // We could hijack Connection Group Name to identify // a desired security exception. But at the moment we'll use a dummy header instead. -// Request.ConnectionGroupName = "NoVerify"; Request.Headers.Add("NoVerifyCert", "true"); } -// else -// { -// Request.ConnectionGroupName="Verify"; -// } if (proxyurl != null && proxyurl.Length > 0) { if (proxyexcepts != null && proxyexcepts.Length > 0) @@ -485,9 +509,9 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest ResponseBody = sb.ToString().Replace("\r", ""); } - catch (Exception e) + catch (WebException e) { - if (e is WebException && ((WebException)e).Status == WebExceptionStatus.ProtocolError) + if (e.Status == WebExceptionStatus.ProtocolError) { HttpWebResponse webRsp = (HttpWebResponse)((WebException)e).Response; Status = (int)webRsp.StatusCode; @@ -512,6 +536,10 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest _finished = true; return; } + catch (Exception e) + { + // Don't crash on anything else + } finally { if (response != null) @@ -525,7 +553,10 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest { try { - httpThread.Abort(); + if (!WorkItem.Cancel()) + { + WorkItem.Abort(); + } } catch (Exception) { diff --git a/prebuild.xml b/prebuild.xml index 7fff2e04d3..fa2172268c 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -1680,6 +1680,7 @@ + From 0e17887e03fb6d32cdd07838caa56e34103ae8f2 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 21 Jan 2013 01:46:40 +0100 Subject: [PATCH 05/14] Allow TeleportCancel packets to reset the transfer state machine --- .../Framework/EntityTransfer/EntityTransferModule.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 7e72d4747f..0c8a2b17ad 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -150,6 +150,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { client.OnTeleportHomeRequest += TriggerTeleportHome; client.OnTeleportLandmarkRequest += RequestTeleportLandmark; + client.OnTeleportCancel += TeleportCancel; } public virtual void Close() {} @@ -993,6 +994,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return neighbourRegion; } + private void TeleportCancel(IClientAPI remoteClient) + { + m_entityTransferStateMachine.ResetFromTransit(remoteClient.AgentId); + } + public bool Cross(ScenePresence agent, bool isFlying) { uint x; From 80529a6baca35e61e684fa3eb1a40c141101ff2c Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 21 Jan 2013 01:47:09 +0100 Subject: [PATCH 06/14] Prevent scene from holding references to SOGs with attargets beyond SOG deletion --- OpenSim/Region/Framework/Scenes/Scene.cs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 23006f2df6..9d07537973 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -282,7 +282,7 @@ namespace OpenSim.Region.Framework.Scenes private readonly Timer m_restartTimer = new Timer(15000); // Wait before firing private volatile bool m_backingup; private Dictionary m_returns = new Dictionary(); - private Dictionary m_groupsWithTargets = new Dictionary(); + private Dictionary m_groupsWithTargets = new Dictionary(); private bool m_physics_enabled = true; private bool m_scripts_enabled = true; @@ -1736,7 +1736,7 @@ namespace OpenSim.Region.Framework.Scenes public void AddGroupTarget(SceneObjectGroup grp) { lock (m_groupsWithTargets) - m_groupsWithTargets[grp.UUID] = grp; + m_groupsWithTargets[grp.UUID] = 0; } public void RemoveGroupTarget(SceneObjectGroup grp) @@ -1747,18 +1747,24 @@ namespace OpenSim.Region.Framework.Scenes private void CheckAtTargets() { - List objs = null; + List objs = null; lock (m_groupsWithTargets) { if (m_groupsWithTargets.Count != 0) - objs = new List(m_groupsWithTargets.Values); + objs = new List(m_groupsWithTargets.Keys); } if (objs != null) { - foreach (SceneObjectGroup entry in objs) - entry.checkAtTargets(); + foreach (UUID entry in objs) + { + SceneObjectGroup grp = GetSceneObjectGroup(entry); + if (grp == null) + m_groupsWithTargets.Remove(entry); + else + grp.checkAtTargets(); + } } } From a291e6be93ada150e35e141dbeb37a31d580f87d Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 21 Jan 2013 01:47:54 +0100 Subject: [PATCH 07/14] Limit active at targets to 8 --- OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index b4749796ec..17f5a0f1dc 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -320,8 +320,8 @@ namespace OpenSim.Region.Framework.Scenes protected SceneObjectPart m_rootPart; // private Dictionary m_scriptEvents = new Dictionary(); - private Dictionary m_targets = new Dictionary(); - private Dictionary m_rotTargets = new Dictionary(); + private SortedDictionary m_targets = new SortedDictionary(); + private SortedDictionary m_rotTargets = new SortedDictionary(); private bool m_scriptListens_atTarget; private bool m_scriptListens_notAtTarget; @@ -4112,6 +4112,8 @@ namespace OpenSim.Region.Framework.Scenes waypoint.handle = handle; lock (m_rotTargets) { + if (m_rotTargets.Count >= 8) + m_rotTargets.Remove(m_rotTargets.ElementAt(0).Key); m_rotTargets.Add(handle, waypoint); } m_scene.AddGroupTarget(this); @@ -4137,6 +4139,8 @@ namespace OpenSim.Region.Framework.Scenes waypoint.handle = handle; lock (m_targets) { + if (m_targets.Count >= 8) + m_targets.Remove(m_targets.ElementAt(0).Key); m_targets.Add(handle, waypoint); } m_scene.AddGroupTarget(this); From da6f589885b7acf5f85aaeb2c011792b9d41a22e Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 21 Jan 2013 08:36:21 +0100 Subject: [PATCH 08/14] Add accessors to allow serializing rot and position targets --- .../Region/Framework/Scenes/SceneObjectGroup.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 17f5a0f1dc..ed1bbd8827 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -79,14 +79,14 @@ namespace OpenSim.Region.Framework.Scenes object_rez = 4194304 } - struct scriptPosTarget + public struct scriptPosTarget { public Vector3 targetPos; public float tolerance; public uint handle; } - struct scriptRotTarget + public struct scriptRotTarget { public Quaternion targetRot; public float tolerance; @@ -323,6 +323,16 @@ namespace OpenSim.Region.Framework.Scenes private SortedDictionary m_targets = new SortedDictionary(); private SortedDictionary m_rotTargets = new SortedDictionary(); + public SortedDictionary AtTargets + { + get { return m_targets; } + } + + public SortedDictionary RotTargets + { + get { return m_rotTargets; } + } + private bool m_scriptListens_atTarget; private bool m_scriptListens_notAtTarget; private bool m_scriptListens_atRotTarget; From 09a3e134e4fd9300899131f13b5be1494a767970 Mon Sep 17 00:00:00 2001 From: teravus Date: Mon, 21 Jan 2013 17:30:38 -0500 Subject: [PATCH 09/14] * Fix notecard loading - If the notecard name is formatted like a UUID but isn't an actual asset UUID, then try to load it like an asset id first, then try to load it as a task inventoryitem name. If the passed UUID is a string, try to load it like a task inventory item name. --- .../Shared/Api/Implementation/OSSL_Api.cs | 46 ++++++++++++++----- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 51c8c7ed89..7c2f8edbca 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -1821,17 +1821,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { UUID assetID = UUID.Zero; - if (!UUID.TryParse(notecardNameOrUuid, out assetID)) + bool notecardNameIsUUID = UUID.TryParse(notecardNameOrUuid, out assetID); + + if (!notecardNameIsUUID) { - m_host.TaskInventory.LockItemsForRead(true); - foreach (TaskInventoryItem item in m_host.TaskInventory.Values) - { - if (item.Type == 7 && item.Name == notecardNameOrUuid) - { - assetID = item.AssetID; - } - } - m_host.TaskInventory.LockItemsForRead(false); + assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid); } if (assetID == UUID.Zero) @@ -1842,7 +1836,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api AssetBase a = World.AssetService.Get(assetID.ToString()); if (a == null) - return UUID.Zero; + { + // Whoops, it's still possible here that the notecard name was properly + // formatted like a UUID but isn't an asset UUID so lets look it up by name after all + assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid); + if (assetID == UUID.Zero) + return UUID.Zero; + + if (!NotecardCache.IsCached(assetID)) + { + a = World.AssetService.Get(assetID.ToString()); + + if (a == null) + { + return UUID.Zero; + } + } + } string data = Encoding.UTF8.GetString(a.Data); NotecardCache.Cache(assetID, data); @@ -1850,6 +1860,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return assetID; } + protected UUID SearchTaskInventoryForAssetId(string name) + { + UUID assetId = UUID.Zero; + m_host.TaskInventory.LockItemsForRead(true); + foreach (TaskInventoryItem item in m_host.TaskInventory.Values) + { + if (item.Type == 7 && item.Name == name) + { + assetId = item.AssetID; + } + } + m_host.TaskInventory.LockItemsForRead(false); + return assetId; + } /// /// Directly get an entire notecard at once. From 89676b8a48c30647f0150c7e2b0da0ba6c932265 Mon Sep 17 00:00:00 2001 From: teravus Date: Mon, 21 Jan 2013 21:32:48 -0500 Subject: [PATCH 10/14] * The fallthrough of FetchTexture was no longer resulting in a 404 response on missing textures. It was just waiting and no event was being provided. This re-enables the 404 response. --- .../Handlers/GetTexture/GetTextureHandler.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs index 6437d0b7b0..f667b8f30a 100644 --- a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs +++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs @@ -176,8 +176,17 @@ namespace OpenSim.Capabilities.Handlers return true; } + response = new Hashtable(); + + response["int_response_code"] = 404; + response["str_response_string"] = "not found"; + response["content_type"] = "text/plain"; + response["keepalive"] = false; + response["reusecontext"] = false; + response["int_bytes"] = 0; + //WriteTextureData(request,response,null,format); // not found -// m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found"); + //m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found"); return true; } From be60c0b0105e2d6929bb331ff86dfbcc45261221 Mon Sep 17 00:00:00 2001 From: teravus Date: Mon, 21 Jan 2013 22:08:51 -0500 Subject: [PATCH 11/14] * A better way to handle the last fix (This is in case the viewer provides a list of preferred formats, though, technically, the sim would pick the first provided format the old way). This just makes it more obvious what's happening. --- .../Handlers/GetTexture/GetTextureHandler.cs | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs index f667b8f30a..68686c5648 100644 --- a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs +++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs @@ -99,12 +99,23 @@ namespace OpenSim.Capabilities.Handlers } // OK, we have an array with preferred formats, possibly with only one entry - + bool foundtexture = false; foreach (string f in formats) { - if (FetchTexture(request, ret, textureID, f)) + foundtexture = FetchTexture(request, ret, textureID, f); + if (foundtexture) break; } + if (!foundtexture) + { + ret["int_response_code"] = 404; + ret["error_status_text"] = "not found"; + ret["str_response_string"] = "not found"; + ret["content_type"] = "text/plain"; + ret["keepalive"] = false; + ret["reusecontext"] = false; + ret["int_bytes"] = 0; + } } else { @@ -176,18 +187,13 @@ namespace OpenSim.Capabilities.Handlers return true; } - response = new Hashtable(); + //response = new Hashtable(); - response["int_response_code"] = 404; - response["str_response_string"] = "not found"; - response["content_type"] = "text/plain"; - response["keepalive"] = false; - response["reusecontext"] = false; - response["int_bytes"] = 0; + //WriteTextureData(request,response,null,format); // not found //m_log.Warn("[GETTEXTURE]: Texture " + textureID + " not found"); - return true; + return false; } private void WriteTextureData(Hashtable request, Hashtable response, AssetBase texture, string format) From f667428283654f4fbe34ddf4cabaa1b991098258 Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 23 Jan 2013 16:11:37 +0100 Subject: [PATCH 12/14] Guard against XMLRPC module ref being null, which will happen if it's disabled --- .../ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index fcb68b2896..58c2ac547e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -7322,7 +7322,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface(); - if (xmlrpcMod.IsEnabled()) + if (xmlrpcMod != null && xmlrpcMod.IsEnabled()) { UUID channelID = xmlrpcMod.OpenXMLRPCChannel(m_host.LocalId, m_item.ItemID, UUID.Zero); IXmlRpcRouter xmlRpcRouter = m_ScriptEngine.World.RequestModuleInterface(); @@ -7354,6 +7354,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.AddScriptLPS(1); IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface(); ScriptSleep(3000); + if (xmlrpcMod == null) + return ""; return (xmlrpcMod.SendRemoteData(m_host.LocalId, m_item.ItemID, channel, dest, idata, sdata)).ToString(); } @@ -7361,7 +7363,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface(); - xmlrpcMod.RemoteDataReply(channel, message_id, sdata, idata); + if (xmlrpcMod != null) + xmlrpcMod.RemoteDataReply(channel, message_id, sdata, idata); ScriptSleep(3000); } @@ -7369,7 +7372,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { m_host.AddScriptLPS(1); IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface(); - xmlrpcMod.CloseXMLRPCChannel((UUID)channel); + if (xmlrpcMod != null) + xmlrpcMod.CloseXMLRPCChannel((UUID)channel); ScriptSleep(1000); } From 997d53e5320e016027eb915fb67de96b501752bb Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 23 Jan 2013 18:17:49 +0100 Subject: [PATCH 13/14] EXPERIMENTAL - Comment out the check for the agent already being in transit to prevent avatars being locked into their sim on a failed teleport. May have side effects and must be revisited to fix right. --- .../EntityTransfer/EntityTransferModule.cs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 0c8a2b17ad..cb09047ad8 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -402,14 +402,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { // Record that this agent is in transit so that we can prevent simultaneous requests and do later detection // of whether the destination region completes the teleport. - if (!m_entityTransferStateMachine.SetInTransit(sp.UUID)) - { - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2} ({3}) {4}/{5} - agent is already in transit.", - sp.Name, sp.UUID, reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position); - - return; - } + m_entityTransferStateMachine.SetInTransit(sp.UUID); +// if (!m_entityTransferStateMachine.SetInTransit(sp.UUID)) +// { +// m_log.DebugFormat( +// "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2} ({3}) {4}/{5} - agent is already in transit.", +// sp.Name, sp.UUID, reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position); +// +// return; +// } if (reg == null || finalDestination == null) { From 47f18caa22fe6bfc6020c80d61c92e4ab8efa86f Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 23 Jan 2013 18:58:29 +0100 Subject: [PATCH 14/14] Remove the return value from llGiveMoney (it was a LSL extension of OpenSim) and make the function async so the script thread is not held up waiting for comms to an external server. --- .../Shared/Api/Implementation/LSL_Api.cs | 54 +++++++++---------- .../Shared/Api/Interface/ILSL_Api.cs | 2 +- .../Shared/Api/Runtime/LSL_Stub.cs | 4 +- 3 files changed, 29 insertions(+), 31 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 58c2ac547e..0562c7fcb4 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3017,42 +3017,40 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return src.ToLower(); } - public LSL_Integer llGiveMoney(string destination, int amount) + public void llGiveMoney(string destination, int amount) { - m_host.AddScriptLPS(1); - - if (m_item.PermsGranter == UUID.Zero) - return 0; - - if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0) + Util.FireAndForget(x => { - LSLError("No permissions to give money"); - return 0; - } + m_host.AddScriptLPS(1); - UUID toID = new UUID(); + if (m_item.PermsGranter == UUID.Zero) + return; - if (!UUID.TryParse(destination, out toID)) - { - LSLError("Bad key in llGiveMoney"); - return 0; - } + if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0) + { + LSLError("No permissions to give money"); + return; + } - IMoneyModule money = World.RequestModuleInterface(); + UUID toID = new UUID(); - if (money == null) - { - NotImplemented("llGiveMoney"); - return 0; - } + if (!UUID.TryParse(destination, out toID)) + { + LSLError("Bad key in llGiveMoney"); + return; + } - bool result = money.ObjectGiveMoney( - m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero); + IMoneyModule money = World.RequestModuleInterface(); - if (result) - return 1; + if (money == null) + { + NotImplemented("llGiveMoney"); + return; + } - return 0; + money.ObjectGiveMoney( + m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero); + }); } public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) @@ -12589,7 +12587,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } bool result = money.ObjectGiveMoney( - m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero); + m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount, txn); if (result) { diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs index 9bf6f9b62c..8eeb4d200e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs @@ -208,7 +208,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces LSL_Float llGetWallclock(); void llGiveInventory(string destination, string inventory); void llGiveInventoryList(string destination, string category, LSL_List inventory); - LSL_Integer llGiveMoney(string destination, int amount); + void llGiveMoney(string destination, int amount); LSL_String llTransferLindenDollars(string destination, int amount); void llGodLikeRezObject(string inventory, LSL_Vector pos); LSL_Float llGround(LSL_Vector offset); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs index 8ecc4f86aa..ef71d7b7f6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs @@ -876,9 +876,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase m_LSL_Functions.llGiveInventoryList(destination, category, inventory); } - public LSL_Integer llGiveMoney(string destination, int amount) + public void llGiveMoney(string destination, int amount) { - return m_LSL_Functions.llGiveMoney(destination, amount); + m_LSL_Functions.llGiveMoney(destination, amount); } public LSL_String llTransferLindenDollars(string destination, int amount)