From 4f9825961743684dfb76827e2353497182a83d8a Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 9 Nov 2012 20:39:55 -0800 Subject: [PATCH] Minor improvement in the MapSearchModule. Stop blocking the client thread if the search takes too long. --- .../World/WorldMap/MapSearchModule.cs | 74 ++++++++++++++----- 1 file changed, 55 insertions(+), 19 deletions(-) diff --git a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs index 7de1bb2cf7..8f1a35ded9 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/MapSearchModule.cs @@ -45,6 +45,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap Scene m_scene = null; // only need one for communication with GridService List m_scenes = new List(); + List m_Clients; #region ISharedRegionModule Members public void Initialise(IConfigSource source) @@ -60,6 +61,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap m_scenes.Add(scene); scene.EventManager.OnNewClient += OnNewClient; + m_Clients = new List(); } public void RemoveRegion(Scene scene) @@ -98,17 +100,51 @@ namespace OpenSim.Region.CoreModules.World.WorldMap private void OnNewClient(IClientAPI client) { - client.OnMapNameRequest += OnMapNameRequest; + client.OnMapNameRequest += OnMapNameRequestHandler; + } + + private void OnMapNameRequestHandler(IClientAPI remoteClient, string mapName, uint flags) + { + lock (m_Clients) + { + if (m_Clients.Contains(remoteClient.AgentId)) + return; + + m_Clients.Add(remoteClient.AgentId); + } + + Util.FireAndForget(delegate + { + try + { + OnMapNameRequest(remoteClient, mapName, flags); + } + finally + { + lock (m_Clients) + m_Clients.Remove(remoteClient.AgentId); + } + }); + } private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags) { - if (mapName.Length < 3) + List blocks = new List(); + MapBlockData data; + if (mapName.Length < 3 || (mapName.EndsWith("#") && mapName.Length < 4)) { + // final block, closing the search result + AddFinalBlock(blocks); + + // flags are agent flags sent from the viewer. + // they have different values depending on different viewers, apparently + remoteClient.SendMapBlock(blocks, flags); remoteClient.SendAlertMessage("Use a search string with at least 3 characters"); return; } + //m_log.DebugFormat("MAP NAME=({0})", mapName); // Hack to get around the fact that ll V3 now drops the port from the @@ -129,13 +165,8 @@ namespace OpenSim.Region.CoreModules.World.WorldMap // try to fetch from GridServer List regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); - if (regionInfos.Count == 0) - remoteClient.SendAlertMessage("Hyperlink could not be established."); m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions. Flags={2}", mapName, regionInfos.Count, flags); - List blocks = new List(); - - MapBlockData data; if (regionInfos.Count > 0) { foreach (GridRegion info in regionInfos) @@ -162,16 +193,7 @@ namespace OpenSim.Region.CoreModules.World.WorldMap } // final block, closing the search result - data = new MapBlockData(); - data.Agents = 0; - data.Access = 255; - data.MapImageId = UUID.Zero; - data.Name = ""; // mapName; - data.RegionFlags = 0; - data.WaterHeight = 0; // not used - data.X = 0; - data.Y = 0; - blocks.Add(data); + AddFinalBlock(blocks); // flags are agent flags sent from the viewer. // they have different values depending on different viewers, apparently @@ -183,12 +205,26 @@ namespace OpenSim.Region.CoreModules.World.WorldMap if (flags == 2) { if (regionInfos.Count == 0) - remoteClient.SendAgentAlertMessage("No regions found with that name.", true); + remoteClient.SendAlertMessage("No regions found with that name."); else if (regionInfos.Count == 1) - remoteClient.SendAgentAlertMessage("Region found!", false); + remoteClient.SendAlertMessage("Region found!"); } } + private void AddFinalBlock(List blocks) + { + // final block, closing the search result + MapBlockData data = new MapBlockData(); + data.Agents = 0; + data.Access = 255; + data.MapImageId = UUID.Zero; + data.Name = ""; + data.RegionFlags = 0; + data.WaterHeight = 0; // not used + data.X = 0; + data.Y = 0; + blocks.Add(data); + } // private Scene GetClientScene(IClientAPI client) // { // foreach (Scene s in m_scenes)