diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index 6be2bd7501..5909ce1af9 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -1158,6 +1158,7 @@ namespace OpenSim.Framework /// /// void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId); + void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId); void SendRemoveInventoryItem(UUID itemID); diff --git a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs index db088e75a2..c13c65bc37 100644 --- a/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs +++ b/OpenSim/Framework/Servers/HttpServer/PollServiceRequestManager.cs @@ -33,6 +33,7 @@ using log4net; using HttpServer; using OpenSim.Framework; using OpenSim.Framework.Monitoring; +using Amib.Threading; /* @@ -185,6 +186,8 @@ namespace OpenSim.Framework.Servers.HttpServer private bool m_running = true; private int slowCount = 0; + private SmartThreadPool m_threadPool = new SmartThreadPool(20000, 12, 2); + // private int m_timeout = 1000; // increase timeout 250; now use the event one public PollServiceRequestManager(BaseHttpServer pSrv, uint pWorkerThreadCount, int pTimeout) @@ -353,17 +356,45 @@ namespace OpenSim.Framework.Servers.HttpServer continue; } - try + // "Normal" means the viewer evebt queue. We need to push these out fast. + // Process them inline. The rest go to the thread pool. + if (req.PollServiceArgs.Type == PollServiceEventArgs.EventType.Normal) { - Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id, str.ReadToEnd()); - DoHTTPGruntWork(m_server, req, responsedata); + try + { + Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id, str.ReadToEnd()); + DoHTTPGruntWork(m_server, req, responsedata); + } + catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream + { + // Ignore it, no need to reply + } + finally + { + str.Close(); + } } - catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream + else { - // Ignore it, no need to reply - } + m_threadPool.QueueWorkItem(x => + { + try + { + Hashtable responsedata = req.PollServiceArgs.GetEvents(req.RequestID, req.PollServiceArgs.Id, str.ReadToEnd()); + DoHTTPGruntWork(m_server, req, responsedata); + } + catch (ObjectDisposedException) // Browser aborted before we could read body, server closed the stream + { + // Ignore it, no need to reply + } + finally + { + str.Close(); + } - str.Close(); + return null; + }, null); + } } else diff --git a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs index f03d8d816c..66bb42921d 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/BunchOfCaps/MeshCost.cs @@ -35,10 +35,13 @@ namespace OpenSim.Region.ClientStack.Linden // fees are normalized to 1.0 // this parameters scale them to basic cost ( so 1.0 translates to 10 ) - public float ModelMeshCostFactor = 1.0f; // scale total cost relative to basic (excluding textures) - public float ModelTextureCostFactor = 1.0f; // scale textures fee to basic. - public float ModelMinCostFactor = 0.5f; // minimum total model free excluding textures + public float ModelMeshCostFactor = 0f; //Free + public float ModelMinCostFactor = 0f; // Free + //public float ModelMeshCostFactor = 1.0f; // scale total cost relative to basic (excluding textures) + //public float ModelMinCostFactor = 0.5f; // minimum total model free excluding textures + public float ModelTextureCostFactor = 1.00f; // keep full price because texture price + // is based on it's storage needs not on usability // itens costs in normalized values // ie will be multiplied by basicCost and factors above const float primCreationCost = 0.002f; // extra cost for each prim creation overhead diff --git a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs index 0ac56ec73f..20002798a2 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/GetTextureModule.cs @@ -146,14 +146,14 @@ namespace OpenSim.Region.ClientStack.Linden { m_scene = scene; - HasEvents = (x, y) => { return this.responses.ContainsKey(x); }; + HasEvents = (x, y) => { lock (responses) return responses.ContainsKey(x); }; GetEvents = (x, y, s) => { lock (responses) { try { - return this.responses[x]; + return responses[x]; } finally { @@ -165,15 +165,15 @@ namespace OpenSim.Region.ClientStack.Linden Request = (x, y) => { y["RequestID"] = x.ToString(); - lock (this.requests) - this.requests.Add(y); + lock (requests) + requests.Add(y); m_queue.Enqueue(this); }; NoEvents = (x, y) => { - lock (this.requests) + lock (requests) { Hashtable request = requests.Find(id => id["RequestID"].ToString() == x.ToString()); requests.Remove(request); @@ -198,7 +198,7 @@ namespace OpenSim.Region.ClientStack.Linden try { - lock (this.requests) + lock (requests) { request = requests[0]; requests.RemoveAt(0); @@ -221,8 +221,10 @@ namespace OpenSim.Region.ClientStack.Linden response["content_type"] = "text/plain"; response["keepalive"] = false; response["reusecontext"] = false; + lock (responses) responses[requestID] = response; + return; } diff --git a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs index 4908c2c7e1..f76ea7426b 100644 --- a/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs +++ b/OpenSim/Region/ClientStack/Linden/Caps/WebFetchInvDescModule.cs @@ -144,31 +144,34 @@ namespace OpenSim.Region.ClientStack.Linden public PollServiceInventoryEventArgs(UUID pId) : base(null, null, null, null, pId, 30000) { - HasEvents = (x, y) => { return this.responses.ContainsKey(x); }; + HasEvents = (x, y) => { lock (responses) return responses.ContainsKey(x); }; GetEvents = (x, y, s) => { - try + lock (responses) { - return this.responses[x]; - } - finally - { - responses.Remove(x); + try + { + return responses[x]; + } + finally + { + responses.Remove(x); + } } }; Request = (x, y) => { y["RequestID"] = x.ToString(); - lock (this.requests) - this.requests.Add(y); + lock (requests) + requests.Add(y); m_queue.Enqueue(this); }; NoEvents = (x, y) => { - lock (this.requests) + lock (requests) { Hashtable request = requests.Find(id => id["RequestID"].ToString() == x.ToString()); requests.Remove(request); @@ -192,7 +195,7 @@ namespace OpenSim.Region.ClientStack.Linden try { - lock (this.requests) + lock (requests) { request = requests[0]; requests.RemoveAt(0); @@ -214,7 +217,8 @@ namespace OpenSim.Region.ClientStack.Linden response["str_response_string"] = m_webFetchHandler.FetchInventoryDescendentsRequest(request["body"].ToString(), String.Empty, String.Empty, null, null); - responses[requestID] = response; + lock (responses) + responses[requestID] = response; } } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 7749ef3890..ee2891451b 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -2067,8 +2067,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(bulkUpdate, ThrottleOutPacketType.Asset); } - /// IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase) public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId) + { + SendInventoryItemCreateUpdate(Item, UUID.Zero, callbackId); + } + + /// IClientAPI.SendInventoryItemCreateUpdate(InventoryItemBase) + public void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId) { const uint FULL_MASK_PERMISSIONS = (uint)PermissionMask.All; @@ -2079,6 +2084,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // TODO: don't create new blocks if recycling an old packet InventoryReply.AgentData.AgentID = AgentId; InventoryReply.AgentData.SimApproved = true; + InventoryReply.AgentData.TransactionID = transactionID; InventoryReply.InventoryData = new UpdateCreateInventoryItemPacket.InventoryDataBlock[1]; InventoryReply.InventoryData[0] = new UpdateCreateInventoryItemPacket.InventoryDataBlock(); InventoryReply.InventoryData[0].ItemID = Item.ID; diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs index b557ffe5f2..8a4fd8f041 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs @@ -146,7 +146,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction } } - public void RequestCreateInventoryItem(IClientAPI remoteClient, + public bool RequestCreateInventoryItem(IClientAPI remoteClient, UUID transactionID, UUID folderID, uint callbackID, string description, string name, sbyte invType, sbyte type, byte wearableType, uint nextOwnerMask) @@ -160,14 +160,16 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction } if (uploader != null) + { uploader.RequestCreateInventoryItem( remoteClient, transactionID, folderID, callbackID, description, name, invType, type, wearableType, nextOwnerMask); - else - m_log.ErrorFormat( - "[AGENT ASSET TRANSACTIONS]: Could not find uploader with transaction ID {0} when handling request to create inventory item {1} from {2}", - transactionID, name, remoteClient.Name); + + return true; + } + + return false; } /// diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs index 708198923a..441c4ff405 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs @@ -158,7 +158,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction /// /// /// - public void HandleItemCreationFromTransaction(IClientAPI remoteClient, + public bool HandleItemCreationFromTransaction(IClientAPI remoteClient, UUID transactionID, UUID folderID, uint callbackID, string description, string name, sbyte invType, sbyte type, byte wearableType, uint nextOwnerMask) @@ -169,7 +169,7 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); - transactions.RequestCreateInventoryItem(remoteClient, transactionID, + return transactions.RequestCreateInventoryItem(remoteClient, transactionID, folderID, callbackID, description, name, invType, type, wearableType, nextOwnerMask); } diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 9a56f42567..50f5f68ab9 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -186,45 +186,44 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess if (folder == null || folder.Owner != remoteClient.AgentId) return; - if (transactionID == UUID.Zero) - { - ScenePresence presence; - if (m_Scene.TryGetScenePresence(remoteClient.AgentId, out presence)) - { - byte[] data = null; - - if (invType == (sbyte)InventoryType.Landmark && presence != null) - { - string suffix = string.Empty, prefix = string.Empty; - string strdata = GenerateLandmark(presence, out prefix, out suffix); - data = Encoding.ASCII.GetBytes(strdata); - name = prefix + name; - description += suffix; - } - - AssetBase asset = m_Scene.CreateAsset(name, description, assetType, data, remoteClient.AgentId); - m_Scene.AssetService.Store(asset); - m_Scene.CreateNewInventoryItem( - remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, - name, description, 0, callbackID, asset, invType, nextOwnerMask, creationDate); - } - else - { - m_log.ErrorFormat( - "[INVENTORY ACCESS MODULE]: ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem", - remoteClient.AgentId); - } - } - else + if (transactionID != UUID.Zero) { IAgentAssetTransactions agentTransactions = m_Scene.AgentTransactionsModule; if (agentTransactions != null) { - agentTransactions.HandleItemCreationFromTransaction( + if (agentTransactions.HandleItemCreationFromTransaction( remoteClient, transactionID, folderID, callbackID, description, - name, invType, assetType, wearableType, nextOwnerMask); + name, invType, assetType, wearableType, nextOwnerMask)) + return; } } + + ScenePresence presence; + if (m_Scene.TryGetScenePresence(remoteClient.AgentId, out presence)) + { + byte[] data = null; + + if (invType == (sbyte)InventoryType.Landmark && presence != null) + { + string suffix = string.Empty, prefix = string.Empty; + string strdata = GenerateLandmark(presence, out prefix, out suffix); + data = Encoding.ASCII.GetBytes(strdata); + name = prefix + name; + description += suffix; + } + + AssetBase asset = m_Scene.CreateAsset(name, description, assetType, data, remoteClient.AgentId); + m_Scene.AssetService.Store(asset); + m_Scene.CreateNewInventoryItem( + remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, + name, description, 0, callbackID, asset, invType, nextOwnerMask, creationDate,transactionID); + } + else + { + m_log.ErrorFormat( + "[INVENTORY ACCESS MODULE]: ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem", + remoteClient.AgentId); + } } protected virtual string GenerateLandmark(ScenePresence presence, out string prefix, out string suffix) diff --git a/OpenSim/Region/Framework/Interfaces/IAgentAssetTransactions.cs b/OpenSim/Region/Framework/Interfaces/IAgentAssetTransactions.cs index 0cc8fb6acd..e0aad2b1d8 100644 --- a/OpenSim/Region/Framework/Interfaces/IAgentAssetTransactions.cs +++ b/OpenSim/Region/Framework/Interfaces/IAgentAssetTransactions.cs @@ -36,7 +36,7 @@ namespace OpenSim.Region.Framework.Interfaces void HandleItemUpdateFromTransaction(IClientAPI remoteClient, UUID transactionID, InventoryItemBase item); - void HandleItemCreationFromTransaction(IClientAPI remoteClient, UUID transactionID, UUID folderID, + bool HandleItemCreationFromTransaction(IClientAPI remoteClient, UUID transactionID, UUID folderID, uint callbackID, string description, string name, sbyte invType, sbyte type, byte wearableType, uint nextOwnerMask); diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 2d9a03568c..dd9210fd55 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -904,11 +904,22 @@ namespace OpenSim.Region.Framework.Scenes public void CreateNewInventoryItem( IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID, string name, string description, uint flags, uint callbackID, - AssetBase asset, sbyte invType, uint nextOwnerMask, int creationDate) + AssetBase asset, sbyte invType, uint nextOwnerMask, int creationDate, UUID transationID) { CreateNewInventoryItem( remoteClient, creatorID, creatorData, folderID, name, description, flags, callbackID, asset, invType, - (uint)PermissionMask.All, (uint)PermissionMask.All, 0, nextOwnerMask, 0, creationDate); + (uint)PermissionMask.All, (uint)PermissionMask.All, 0, nextOwnerMask, 0, creationDate, transationID); + } + + + private void CreateNewInventoryItem( + IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID, + string name, string description, uint flags, uint callbackID, AssetBase asset, sbyte invType, + uint baseMask, uint currentMask, uint everyoneMask, uint nextOwnerMask, uint groupMask, int creationDate) + { + CreateNewInventoryItem(remoteClient, creatorID, creatorData, folderID, + name, description, flags, callbackID, asset, invType, + baseMask, currentMask, everyoneMask, nextOwnerMask, groupMask, creationDate, UUID.Zero); } /// @@ -933,7 +944,7 @@ namespace OpenSim.Region.Framework.Scenes private void CreateNewInventoryItem( IClientAPI remoteClient, string creatorID, string creatorData, UUID folderID, string name, string description, uint flags, uint callbackID, AssetBase asset, sbyte invType, - uint baseMask, uint currentMask, uint everyoneMask, uint nextOwnerMask, uint groupMask, int creationDate) + uint baseMask, uint currentMask, uint everyoneMask, uint nextOwnerMask, uint groupMask, int creationDate,UUID transationID) { InventoryItemBase item = new InventoryItemBase(); item.Owner = remoteClient.AgentId; @@ -956,7 +967,7 @@ namespace OpenSim.Region.Framework.Scenes if (AddInventoryItem(item)) { - remoteClient.SendInventoryItemCreateUpdate(item, callbackID); + remoteClient.SendInventoryItemCreateUpdate(item, transationID, callbackID); } else { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 56d289fefb..e6ad89c415 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -2146,10 +2146,10 @@ namespace OpenSim.Region.Framework.Scenes { if (asset != null) SculptTextureCallback(asset); - else - m_log.WarnFormat( - "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data", - Name, UUID, id); +// else +// m_log.WarnFormat( +// "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data", +// Name, UUID, id); } /// diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index 3b83e58933..a484300fd2 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -1100,7 +1100,12 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId) { - + + } + + public void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId) + { + } public void SendRemoveInventoryItem(UUID itemID) diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index d00a6c0516..7c693b6fc8 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -739,6 +739,10 @@ namespace OpenSim.Region.OptionalModules.World.NPC { } + public void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId) + { + } + public virtual void SendRemoveInventoryItem(UUID itemID) { } diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index 6add1305a8..49a8d26f01 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -716,6 +716,10 @@ namespace OpenSim.Tests.Common.Mock { } + public void SendInventoryItemCreateUpdate(InventoryItemBase Item, UUID transactionID, uint callbackId) + { + } + public virtual void SendRemoveInventoryItem(UUID itemID) { } diff --git a/prebuild.xml b/prebuild.xml index d3d040ff2d..a717bb7787 100644 --- a/prebuild.xml +++ b/prebuild.xml @@ -162,6 +162,7 @@ +