From a6a136bd90735b5a15ebc91c8a2a310f7250ac94 Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Mon, 20 Dec 2010 14:15:44 -0800 Subject: [PATCH 01/14] Shooting in the dark for solutions to the appearance problem --- OpenSim/Framework/Capabilities/Caps.cs | 12 ++++++------ .../Servers/HttpServer/BinaryStreamHandler.cs | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/OpenSim/Framework/Capabilities/Caps.cs b/OpenSim/Framework/Capabilities/Caps.cs index 63e1e34b99..dbb07817f6 100644 --- a/OpenSim/Framework/Capabilities/Caps.cs +++ b/OpenSim/Framework/Capabilities/Caps.cs @@ -1344,6 +1344,12 @@ namespace OpenSim.Framework.Capabilities /// public string uploaderCaps(byte[] data, string path, string param) { + handlerUpLoad = OnUpLoad; + if (handlerUpLoad != null) + { + Util.FireAndForget(delegate(object o) { handlerUpLoad(newAssetID, data); }); + } + string res = String.Empty; LLSDAssetUploadComplete uploadComplete = new LLSDAssetUploadComplete(); uploadComplete.new_asset = newAssetID.ToString(); @@ -1354,12 +1360,6 @@ namespace OpenSim.Framework.Capabilities httpListener.RemoveStreamHandler("POST", uploaderPath); - handlerUpLoad = OnUpLoad; - if (handlerUpLoad != null) - { - handlerUpLoad(newAssetID, data); - } - m_log.InfoFormat("[CAPS] baked texture upload completed for {0}",newAssetID); return res; diff --git a/OpenSim/Framework/Servers/HttpServer/BinaryStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/BinaryStreamHandler.cs index 86fa44dfea..bae4e1b997 100644 --- a/OpenSim/Framework/Servers/HttpServer/BinaryStreamHandler.cs +++ b/OpenSim/Framework/Servers/HttpServer/BinaryStreamHandler.cs @@ -53,8 +53,8 @@ namespace OpenSim.Framework.Servers.HttpServer private static byte[] ReadFully(Stream stream) { - byte[] buffer = new byte[32768]; - using (MemoryStream ms = new MemoryStream()) + byte[] buffer = new byte[1024]; + using (MemoryStream ms = new MemoryStream(1024*256)) { while (true) { From 2f84f2171fb7e17f6c336a4e6db9a04ad822704a Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 21 Dec 2010 20:47:00 +0000 Subject: [PATCH 02/14] Make prim inventories a bit more sane --- .../Framework/Interfaces/IEntityInventory.cs | 7 -- .../Framework/Scenes/Scene.Inventory.cs | 23 ++---- .../Scenes/SceneObjectGroup.Inventory.cs | 43 ----------- .../Scenes/SceneObjectPartInventory.cs | 76 ++++++++----------- 4 files changed, 39 insertions(+), 110 deletions(-) diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs index ed40da9609..4b17b9a71f 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs @@ -195,13 +195,6 @@ namespace OpenSim.Region.Framework.Interfaces /// in this prim's inventory. int RemoveInventoryItem(UUID itemID); - /// - /// Return the name with which a client can request a xfer of this prim's inventory metadata - /// - string GetInventoryFileName(); - - bool GetInventoryFileName(IClientAPI client, uint localID); - /// /// Serialize all the metadata for the items in this prim's inventory ready for sending to the client /// diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index a1f1ea5489..47c574a2e4 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -951,23 +951,12 @@ namespace OpenSim.Region.Framework.Scenes /// public void RequestTaskInventory(IClientAPI remoteClient, uint primLocalID) { - SceneObjectGroup group = GetGroupByPrim(primLocalID); - if (group != null) - { - bool fileChange = group.GetPartInventoryFileName(remoteClient, primLocalID); - if (fileChange) - { - if (XferManager != null) - { - group.RequestInventoryFile(remoteClient, primLocalID, XferManager); - } - } - } - else - { - m_log.ErrorFormat( - "[PRIM INVENTORY]: Inventory requested of prim {0} which doesn't exist", primLocalID); - } + SceneObjectPart part = GetSceneObjectPart(primLocalID); + if (part == null) + return; + + if (XferManager != null) + part.Inventory.RequestInventoryFile(remoteClient, XferManager); } /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs index 6cc7231502..50521c45ab 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs @@ -76,49 +76,6 @@ namespace OpenSim.Region.Framework.Scenes parts[i].Inventory.RemoveScriptInstances(sceneObjectBeingDeleted); } - /// - /// - /// - /// - /// - public bool GetPartInventoryFileName(IClientAPI remoteClient, uint localID) - { - SceneObjectPart part = GetChildPart(localID); - if (part != null) - { - return part.Inventory.GetInventoryFileName(remoteClient, localID); - } - else - { - m_log.ErrorFormat( - "[PRIM INVENTORY]: " + - "Couldn't find part {0} in object group {1}, {2} to retreive prim inventory", - localID, Name, UUID); - } - return false; - } - - /// - /// Return serialized inventory metadata for the given constituent prim - /// - /// - /// - public void RequestInventoryFile(IClientAPI client, uint localID, IXfer xferManager) - { - SceneObjectPart part = GetChildPart(localID); - if (part != null) - { - part.Inventory.RequestInventoryFile(client, xferManager); - } - else - { - m_log.ErrorFormat( - "[PRIM INVENTORY]: " + - "Couldn't find part {0} in object group {1}, {2} to request inventory data", - localID, Name, UUID); - } - } - /// /// Add an inventory item to a prim in this group. /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 8fcfcc5e75..74b4e54016 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -46,6 +46,7 @@ namespace OpenSim.Region.Framework.Scenes private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private string m_inventoryFileName = String.Empty; + private byte[] m_inventoryFileData = new byte[0]; private int m_inventoryFileNameSerial = 0; private Dictionary m_scriptErrors = new Dictionary(); @@ -930,39 +931,16 @@ namespace OpenSim.Region.Framework.Scenes return -1; } - public string GetInventoryFileName() + private bool CreateInventoryFileName() { - if (m_inventoryFileName == String.Empty) - m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; - if (m_inventoryFileNameSerial < m_inventorySerial) + if (m_inventoryFileName == String.Empty || + m_inventoryFileNameSerial < m_inventorySerial) { m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; - } - return m_inventoryFileName; - } - - /// - /// Return the name with which a client can request a xfer of this prim's inventory metadata - /// - /// - /// - public bool GetInventoryFileName(IClientAPI client, uint localID) - { -// m_log.DebugFormat( -// "[PRIM INVENTORY]: Received request from client {0} for inventory file name of {1}, {2}", -// client.AgentId, Name, UUID); - - if (m_inventorySerial > 0) - { - client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, - Utils.StringToBytes(GetInventoryFileName())); return true; } - else - { - client.SendTaskInventory(m_part.UUID, 0, new byte[0]); - return false; - } + + return false; } /// @@ -971,19 +949,34 @@ namespace OpenSim.Region.Framework.Scenes /// public void RequestInventoryFile(IClientAPI client, IXfer xferManager) { - byte[] fileData = new byte[0]; + bool changed = CreateInventoryFileName(); - // Confusingly, the folder item has to be the object id, while the 'parent id' has to be zero. This matches - // what appears to happen in the Second Life protocol. If this isn't the case. then various functionality - // isn't available (such as drag from prim inventory to agent inventory) InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); - bool includeAssets = false; - if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId)) - includeAssets = true; - lock (m_items) { + if (m_inventorySerial == 0) // No inventory + { + client.SendTaskInventory(m_part.UUID, 0, new byte[0]); + return; + } + + client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, + Util.StringToBytes256(m_inventoryFileName)); + + if (!changed) + { + if (m_inventoryFileData.Length > 2) + { + xferManager.AddNewFile(m_inventoryFileName, + m_inventoryFileData); + } + } + + bool includeAssets = false; + if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId)) + includeAssets = true; + foreach (TaskInventoryItem item in m_items.Values) { UUID ownerID = item.OwnerID; @@ -1032,17 +1025,14 @@ namespace OpenSim.Region.Framework.Scenes invString.AddSectionEnd(); } } + int count = m_items.Count; - m_items.LockItemsForRead(false); - fileData = Utils.StringToBytes(invString.BuildString); + m_inventoryFileData = Utils.StringToBytes(invString.BuildString); - //m_log.Debug(Utils.BytesToString(fileData)); - //m_log.Debug("[PRIM INVENTORY]: RequestInventoryFile fileData: " + Utils.BytesToString(fileData)); - - if (fileData.Length > 2) + if (m_inventoryFileData.Length > 2) { - xferManager.AddNewFile(m_inventoryFileName, fileData); + xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); } } From c9aa420c2d87da6285007ca52f0defbe60239c91 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 21 Dec 2010 20:48:58 +0000 Subject: [PATCH 03/14] Restore CM loking after core extract --- .../Scenes/SceneObjectPartInventory.cs | 137 +++++++++--------- 1 file changed, 68 insertions(+), 69 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 74b4e54016..8ec9d55144 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -953,80 +953,79 @@ namespace OpenSim.Region.Framework.Scenes InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); - lock (m_items) + Items.LockItemsForRead(true); + + if (m_inventorySerial == 0) // No inventory { - if (m_inventorySerial == 0) // No inventory + client.SendTaskInventory(m_part.UUID, 0, new byte[0]); + return; + } + + client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, + Util.StringToBytes256(m_inventoryFileName)); + + if (!changed) + { + if (m_inventoryFileData.Length > 2) { - client.SendTaskInventory(m_part.UUID, 0, new byte[0]); - return; - } - - client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, - Util.StringToBytes256(m_inventoryFileName)); - - if (!changed) - { - if (m_inventoryFileData.Length > 2) - { - xferManager.AddNewFile(m_inventoryFileName, - m_inventoryFileData); - } - } - - bool includeAssets = false; - if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId)) - includeAssets = true; - - foreach (TaskInventoryItem item in m_items.Values) - { - UUID ownerID = item.OwnerID; - uint everyoneMask = 0; - uint baseMask = item.BasePermissions; - uint ownerMask = item.CurrentPermissions; - uint groupMask = item.GroupPermissions; - - invString.AddItemStart(); - invString.AddNameValueLine("item_id", item.ItemID.ToString()); - invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); - - invString.AddPermissionsStart(); - - invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); - invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); - invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask)); - invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); - invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); - - invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); - invString.AddNameValueLine("owner_id", ownerID.ToString()); - - invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); - - invString.AddNameValueLine("group_id", item.GroupID.ToString()); - invString.AddSectionEnd(); - - if (includeAssets) - invString.AddNameValueLine("asset_id", item.AssetID.ToString()); - else - invString.AddNameValueLine("asset_id", UUID.Zero.ToString()); - invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); - invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); - invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); - - invString.AddSaleStart(); - invString.AddNameValueLine("sale_type", "not"); - invString.AddNameValueLine("sale_price", "0"); - invString.AddSectionEnd(); - - invString.AddNameValueLine("name", item.Name + "|"); - invString.AddNameValueLine("desc", item.Description + "|"); - - invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); - invString.AddSectionEnd(); + xferManager.AddNewFile(m_inventoryFileName, + m_inventoryFileData); } } - int count = m_items.Count; + bool includeAssets = false; + if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId)) + includeAssets = true; + + foreach (TaskInventoryItem item in m_items.Values) + { + UUID ownerID = item.OwnerID; + uint everyoneMask = 0; + uint baseMask = item.BasePermissions; + uint ownerMask = item.CurrentPermissions; + uint groupMask = item.GroupPermissions; + + invString.AddItemStart(); + invString.AddNameValueLine("item_id", item.ItemID.ToString()); + invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); + + invString.AddPermissionsStart(); + + invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); + invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); + invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask)); + invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); + invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); + + invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); + invString.AddNameValueLine("owner_id", ownerID.ToString()); + + invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); + + invString.AddNameValueLine("group_id", item.GroupID.ToString()); + invString.AddSectionEnd(); + + if (includeAssets) + invString.AddNameValueLine("asset_id", item.AssetID.ToString()); + else + invString.AddNameValueLine("asset_id", UUID.Zero.ToString()); + invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); + invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); + invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); + + invString.AddSaleStart(); + invString.AddNameValueLine("sale_type", "not"); + invString.AddNameValueLine("sale_price", "0"); + invString.AddSectionEnd(); + + invString.AddNameValueLine("name", item.Name + "|"); + invString.AddNameValueLine("desc", item.Description + "|"); + + invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); + invString.AddSectionEnd(); + } + + Items.LockItemsForRead(false); m_inventoryFileData = Utils.StringToBytes(invString.BuildString); From 043dace1184b14c1b07863c2ffabaf5e24fb53c4 Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 21 Dec 2010 20:47:00 +0000 Subject: [PATCH 04/14] Make prim inventories a bit more sane --- .../Framework/Interfaces/IEntityInventory.cs | 7 -- .../Framework/Scenes/Scene.Inventory.cs | 23 ++---- .../Scenes/SceneObjectGroup.Inventory.cs | 43 ----------- .../Scenes/SceneObjectPartInventory.cs | 74 +++++++++---------- 4 files changed, 39 insertions(+), 108 deletions(-) diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs index 64664ab033..15060fdd17 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs @@ -193,13 +193,6 @@ namespace OpenSim.Region.Framework.Interfaces /// in this prim's inventory. int RemoveInventoryItem(UUID itemID); - /// - /// Return the name with which a client can request a xfer of this prim's inventory metadata - /// - string GetInventoryFileName(); - - bool GetInventoryFileName(IClientAPI client, uint localID); - /// /// Serialize all the metadata for the items in this prim's inventory ready for sending to the client /// diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 2cf0ced61a..321d0aa1c5 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -949,23 +949,12 @@ namespace OpenSim.Region.Framework.Scenes /// public void RequestTaskInventory(IClientAPI remoteClient, uint primLocalID) { - SceneObjectGroup group = GetGroupByPrim(primLocalID); - if (group != null) - { - bool fileChange = group.GetPartInventoryFileName(remoteClient, primLocalID); - if (fileChange) - { - if (XferManager != null) - { - group.RequestInventoryFile(remoteClient, primLocalID, XferManager); - } - } - } - else - { - m_log.ErrorFormat( - "[PRIM INVENTORY]: Inventory requested of prim {0} which doesn't exist", primLocalID); - } + SceneObjectPart part = GetSceneObjectPart(primLocalID); + if (part == null) + return; + + if (XferManager != null) + part.Inventory.RequestInventoryFile(remoteClient, XferManager); } /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs index a86223c9ba..982e280244 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.Inventory.cs @@ -80,49 +80,6 @@ namespace OpenSim.Region.Framework.Scenes parts[i].Inventory.RemoveScriptInstances(sceneObjectBeingDeleted); } - /// - /// - /// - /// - /// - public bool GetPartInventoryFileName(IClientAPI remoteClient, uint localID) - { - SceneObjectPart part = GetChildPart(localID); - if (part != null) - { - return part.Inventory.GetInventoryFileName(remoteClient, localID); - } - else - { - m_log.ErrorFormat( - "[PRIM INVENTORY]: " + - "Couldn't find part {0} in object group {1}, {2} to retreive prim inventory", - localID, Name, UUID); - } - return false; - } - - /// - /// Return serialized inventory metadata for the given constituent prim - /// - /// - /// - public void RequestInventoryFile(IClientAPI client, uint localID, IXfer xferManager) - { - SceneObjectPart part = GetChildPart(localID); - if (part != null) - { - part.Inventory.RequestInventoryFile(client, xferManager); - } - else - { - m_log.ErrorFormat( - "[PRIM INVENTORY]: " + - "Couldn't find part {0} in object group {1}, {2} to request inventory data", - localID, Name, UUID); - } - } - /// /// Add an inventory item to a prim in this group. /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 6a204c3413..ac69f168c4 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -46,6 +46,7 @@ namespace OpenSim.Region.Framework.Scenes private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private string m_inventoryFileName = String.Empty; + private byte[] m_inventoryFileData = new byte[0]; private int m_inventoryFileNameSerial = 0; /// @@ -765,39 +766,16 @@ namespace OpenSim.Region.Framework.Scenes return -1; } - public string GetInventoryFileName() + private bool CreateInventoryFileName() { - if (m_inventoryFileName == String.Empty) - m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; - if (m_inventoryFileNameSerial < m_inventorySerial) + if (m_inventoryFileName == String.Empty || + m_inventoryFileNameSerial < m_inventorySerial) { m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; - } - return m_inventoryFileName; - } - - /// - /// Return the name with which a client can request a xfer of this prim's inventory metadata - /// - /// - /// - public bool GetInventoryFileName(IClientAPI client, uint localID) - { -// m_log.DebugFormat( -// "[PRIM INVENTORY]: Received request from client {0} for inventory file name of {1}, {2}", -// client.AgentId, Name, UUID); - - if (m_inventorySerial > 0) - { - client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, - Utils.StringToBytes(GetInventoryFileName())); return true; } - else - { - client.SendTaskInventory(m_part.UUID, 0, new byte[0]); - return false; - } + + return false; } /// @@ -806,19 +784,34 @@ namespace OpenSim.Region.Framework.Scenes /// public void RequestInventoryFile(IClientAPI client, IXfer xferManager) { - byte[] fileData = new byte[0]; + bool changed = CreateInventoryFileName(); - // Confusingly, the folder item has to be the object id, while the 'parent id' has to be zero. This matches - // what appears to happen in the Second Life protocol. If this isn't the case. then various functionality - // isn't available (such as drag from prim inventory to agent inventory) InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); - bool includeAssets = false; - if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId)) - includeAssets = true; - lock (m_items) { + if (m_inventorySerial == 0) // No inventory + { + client.SendTaskInventory(m_part.UUID, 0, new byte[0]); + return; + } + + client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, + Util.StringToBytes256(m_inventoryFileName)); + + if (!changed) + { + if (m_inventoryFileData.Length > 2) + { + xferManager.AddNewFile(m_inventoryFileName, + m_inventoryFileData); + } + } + + bool includeAssets = false; + if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId)) + includeAssets = true; + foreach (TaskInventoryItem item in m_items.Values) { UUID ownerID = item.OwnerID; @@ -868,14 +861,13 @@ namespace OpenSim.Region.Framework.Scenes } } - fileData = Utils.StringToBytes(invString.BuildString); + int count = m_items.Count; - //m_log.Debug(Utils.BytesToString(fileData)); - //m_log.Debug("[PRIM INVENTORY]: RequestInventoryFile fileData: " + Utils.BytesToString(fileData)); + m_inventoryFileData = Utils.StringToBytes(invString.BuildString); - if (fileData.Length > 2) + if (m_inventoryFileData.Length > 2) { - xferManager.AddNewFile(m_inventoryFileName, fileData); + xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); } } From a31b96e1ba755122220d4dd8e5e04d721910a2fc Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 21 Dec 2010 20:54:28 +0000 Subject: [PATCH 05/14] Fix up merge artifacts --- .../Framework/Scenes/SceneObjectPartInventory.cs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index ac69f168c4..36c5fc12da 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -808,10 +808,6 @@ namespace OpenSim.Region.Framework.Scenes } } - bool includeAssets = false; - if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId)) - includeAssets = true; - foreach (TaskInventoryItem item in m_items.Values) { UUID ownerID = item.OwnerID; @@ -840,10 +836,7 @@ namespace OpenSim.Region.Framework.Scenes invString.AddNameValueLine("group_id", item.GroupID.ToString()); invString.AddSectionEnd(); - if (includeAssets) - invString.AddNameValueLine("asset_id", item.AssetID.ToString()); - else - invString.AddNameValueLine("asset_id", UUID.Zero.ToString()); + invString.AddNameValueLine("asset_id", item.AssetID.ToString()); invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); @@ -861,8 +854,6 @@ namespace OpenSim.Region.Framework.Scenes } } - int count = m_items.Count; - m_inventoryFileData = Utils.StringToBytes(invString.BuildString); if (m_inventoryFileData.Length > 2) From ec8d1d0131a3e6c28706a29bd2d2d7c4e49d597f Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 21 Dec 2010 22:49:38 +0000 Subject: [PATCH 06/14] Added a missed return. Thanks diva! --- OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 36c5fc12da..dc1447ab54 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -805,6 +805,7 @@ namespace OpenSim.Region.Framework.Scenes { xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); + return; } } From 19181c019ab5af99e5adb74cc4265b63db00021a Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 21 Dec 2010 22:56:48 +0000 Subject: [PATCH 07/14] Another good catch. Update file name serial. --- OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index dc1447ab54..9bf31fa400 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -772,6 +772,7 @@ namespace OpenSim.Region.Framework.Scenes m_inventoryFileNameSerial < m_inventorySerial) { m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; + m_inventoryFileNameSerial = m_inventorySerial; return true; } From 1c3e77b728b8a14e64c0fae6814f3edc4a76b40f Mon Sep 17 00:00:00 2001 From: Melanie Date: Tue, 21 Dec 2010 22:58:52 +0000 Subject: [PATCH 08/14] What is the point of using different types to express the same damn thing? --- OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 9bf31fa400..1177378076 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -47,7 +47,7 @@ namespace OpenSim.Region.Framework.Scenes private string m_inventoryFileName = String.Empty; private byte[] m_inventoryFileData = new byte[0]; - private int m_inventoryFileNameSerial = 0; + private uint m_inventoryFileNameSerial = 0; /// /// The part to which the inventory belongs. From 25ecd62b1feed16d12d6f5e5ef00bddf7dbf0547 Mon Sep 17 00:00:00 2001 From: "Teravus Ovares (Dan Olivares)" Date: Tue, 21 Dec 2010 19:15:44 -0500 Subject: [PATCH 09/14] * Adds AbortXfer to the ClientAPI mix * Adds an item that checks to see if the top request has been there for longer then 30 seconds without an update and sends an AbortXfer if it encounters one. This allows the client to cancel the Xfer on it's side so you can re-select the prim and get the inventory when it fails the first time. * Some interesting locking... Using NewFiles to lock the rest of them. We'll see how that goes. * The goal of this is to ensure that Xfers are restartable when they fail. The client will not do that on it's own. --- .../Client/MXP/ClientStack/MXPClientView.cs | 6 ++ .../VWoHTTP/ClientStack/VWHClientView.cs | 5 ++ OpenSim/Framework/IClientAPI.cs | 2 + .../ClientStack/LindenUDP/LLClientView.cs | 7 ++ .../CoreModules/Agent/Xfer/XferModule.cs | 70 +++++++++++++++++-- .../Examples/SimpleModule/MyNpcCharacter.cs | 6 ++ .../Server/IRCClientView.cs | 5 ++ .../OptionalModules/World/NPC/NPCAvatar.cs | 4 ++ OpenSim/Tests/Common/Mock/TestClient.cs | 5 ++ 9 files changed, 106 insertions(+), 4 deletions(-) diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs index 19331c68bf..a66caab840 100644 --- a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs +++ b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs @@ -1116,6 +1116,12 @@ namespace OpenSim.Client.MXP.ClientStack // SL Specific, Ignore. (Remove from IClient) } + public void SendAbortXferPacket(ulong xferID) + { + + } + + public void SendEconomyData(float EnergyEfficiency, int ObjectCapacity, int ObjectCount, int PriceEnergyUnit, int PriceGroupCreate, int PriceObjectClaim, float PriceObjectRent, float PriceObjectScaleFactor, int PriceParcelClaim, float PriceParcelClaimFactor, int PriceParcelRent, int PricePublicObjectDecay, int PricePublicObjectDelete, int PriceRentLight, int PriceUpload, int TeleportMinPrice, float TeleportPriceExponent) { // SL Specific, Ignore. (Remove from IClient) diff --git a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs index 0d2323251d..c8eca9f62e 100644 --- a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs +++ b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs @@ -669,6 +669,11 @@ namespace OpenSim.Client.VWoHTTP.ClientStack throw new System.NotImplementedException(); } + public virtual void SendAbortXferPacket(ulong xferID) + { + throw new System.NotImplementedException(); + } + public void SendEconomyData(float EnergyEfficiency, int ObjectCapacity, int ObjectCount, int PriceEnergyUnit, int PriceGroupCreate, int PriceObjectClaim, float PriceObjectRent, float PriceObjectScaleFactor, int PriceParcelClaim, float PriceParcelClaimFactor, int PriceParcelRent, int PricePublicObjectDecay, int PricePublicObjectDelete, int PriceRentLight, int PriceUpload, int TeleportMinPrice, float TeleportPriceExponent) { throw new System.NotImplementedException(); diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index b9c932339e..6bca6eb02f 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -1057,6 +1057,8 @@ namespace OpenSim.Framework void SendXferPacket(ulong xferID, uint packet, byte[] data); + void SendAbortXferPacket(ulong xferID); + void SendEconomyData(float EnergyEfficiency, int ObjectCapacity, int ObjectCount, int PriceEnergyUnit, int PriceGroupCreate, int PriceObjectClaim, float PriceObjectRent, float PriceObjectScaleFactor, diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 63469c86be..929f28251c 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -2078,6 +2078,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP OutPacket(sendXfer, ThrottleOutPacketType.Asset); } + public void SendAbortXferPacket(ulong xferID) + { + AbortXferPacket xferItem = (AbortXferPacket)PacketPool.Instance.GetPacket(PacketType.AbortXfer); + xferItem.XferID.ID = xferID; + OutPacket(xferItem, ThrottleOutPacketType.Asset); + } + public void SendEconomyData(float EnergyEfficiency, int ObjectCapacity, int ObjectCount, int PriceEnergyUnit, int PriceGroupCreate, int PriceObjectClaim, float PriceObjectRent, float PriceObjectScaleFactor, int PriceParcelClaim, float PriceParcelClaimFactor, int PriceParcelRent, int PricePublicObjectDecay, diff --git a/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs b/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs index ef7dce812e..57875dac26 100644 --- a/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs +++ b/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs @@ -97,6 +97,7 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer NewFiles.Add(fileName, data); } } + string filename = string.Empty; if (Requests.ContainsKey(fileName)) { @@ -113,6 +114,7 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer { client.OnRequestXfer += RequestXfer; client.OnConfirmXfer += AckPacket; + client.OnAbortXfer += AbortXfer; } /// @@ -125,6 +127,17 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer { lock (NewFiles) { + if (RequestTime.Count > 0) + { + TimeSpan ts = new TimeSpan(DateTime.UtcNow.Ticks - RequestTime[0].timeStamp.Ticks); + if (ts.TotalSeconds > 30) + { + ulong zxferid = RequestTime[0].xferID; + remoteClient.SendAbortXferPacket(zxferid); + RemoveXferData(zxferid); + } + } + if (NewFiles.ContainsKey(fileName)) { if (!Transfers.ContainsKey(xferID)) @@ -137,7 +150,7 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer if (transaction.StartSend()) { - Transfers.Remove(xferID); + RemoveXferData(xferID); } } } @@ -150,6 +163,8 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer { Requests.Remove(RequestTime[0].fileName); RequestTime.RemoveAt(0); + // Do we want to abort this here? + //remoteClient.SendAbortXfer(xferID); } } @@ -165,22 +180,69 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer } } + } } public void AckPacket(IClientAPI remoteClient, ulong xferID, uint packet) { - if (Transfers.ContainsKey(xferID)) + lock (NewFiles) // This is actually to lock Transfers { - if (Transfers[xferID].AckPacket(packet)) + if (Transfers.ContainsKey(xferID)) { + XferDownLoad dl = Transfers[xferID]; + if (Transfers[xferID].AckPacket(packet)) { - Transfers.Remove(xferID); + { + RemoveXferData(xferID); + } + } + else + { + + if (Requests.ContainsKey(dl.FileName)) + { + // + XferRequest req = Requests[dl.FileName]; + req.timeStamp = DateTime.UtcNow; + Requests[dl.FileName] = req; + } } } } } + private void RemoveXferData(ulong xferID) + { + // NewFiles must be locked! + if (Transfers.ContainsKey(xferID)) + { + // Qualifier distinguishes between the OpenMetaverse version and the nested class + + XferModule.XferDownLoad xferItem = Transfers[xferID]; + //string filename = xferItem.FileName; + Transfers.Remove(xferID); + xferItem.Data = new byte[0]; // Clear the data + xferItem.DataPointer = 0; + + // If the abort comes in + if (NewFiles.ContainsKey(xferItem.FileName)) + NewFiles.Remove(xferItem.FileName); + + if (Requests.ContainsKey(xferItem.FileName)) + Requests.Remove(xferItem.FileName); + + } + } + + public void AbortXfer(IClientAPI remoteClient, ulong xferID) + { + lock (NewFiles) + { + RemoveXferData(xferID); + } + } + #region Nested type: XferDownLoad public class XferDownLoad diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index f128aa2da4..311352c032 100644 --- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs +++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs @@ -602,6 +602,12 @@ namespace OpenSim.Region.Examples.SimpleModule { } + public virtual void SendAbortXferPacket(ulong xferID) + { + + } + + public virtual void SendEconomyData(float EnergyEfficiency, int ObjectCapacity, int ObjectCount, int PriceEnergyUnit, int PriceGroupCreate, int PriceObjectClaim, float PriceObjectRent, float PriceObjectScaleFactor, int PriceParcelClaim, float PriceParcelClaimFactor, int PriceParcelRent, int PricePublicObjectDecay, diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs index fc17192b50..20870aa528 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs @@ -1117,6 +1117,11 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server } + public void SendAbortXferPacket(ulong xferID) + { + + } + public void SendEconomyData(float EnergyEfficiency, int ObjectCapacity, int ObjectCount, int PriceEnergyUnit, int PriceGroupCreate, int PriceObjectClaim, float PriceObjectRent, float PriceObjectScaleFactor, int PriceParcelClaim, float PriceParcelClaimFactor, int PriceParcelRent, int PricePublicObjectDecay, int PricePublicObjectDelete, int PriceRentLight, int PriceUpload, int TeleportMinPrice, float TeleportPriceExponent) { diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index 6928c4efbc..0c43c8a9cd 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -686,6 +686,10 @@ namespace OpenSim.Region.OptionalModules.World.NPC public virtual void SendXferPacket(ulong xferID, uint packet, byte[] data) { + } + public virtual void SendAbortXferPacket(ulong xferID) + { + } public virtual void SendEconomyData(float EnergyEfficiency, int ObjectCapacity, int ObjectCount, int PriceEnergyUnit, diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs index b2c8b35ec7..3f3845c1cb 100644 --- a/OpenSim/Tests/Common/Mock/TestClient.cs +++ b/OpenSim/Tests/Common/Mock/TestClient.cs @@ -696,6 +696,11 @@ namespace OpenSim.Tests.Common.Mock { } + public virtual void SendAbortXferPacket(ulong xferID) + { + + } + public virtual void SendEconomyData(float EnergyEfficiency, int ObjectCapacity, int ObjectCount, int PriceEnergyUnit, int PriceGroupCreate, int PriceObjectClaim, float PriceObjectRent, float PriceObjectScaleFactor, int PriceParcelClaim, float PriceParcelClaimFactor, int PriceParcelRent, int PricePublicObjectDecay, From cf37b3b9434ca940fa635c0e951fa9ac7c07175a Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 22 Dec 2010 03:25:30 +0100 Subject: [PATCH 10/14] Prevent a null ref when an avatar login doesn't go as planned --- OpenSim/Framework/Watchdog.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.cs | 3 ++- OpenSim/Region/Framework/Scenes/SceneViewer.cs | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/OpenSim/Framework/Watchdog.cs b/OpenSim/Framework/Watchdog.cs index 9baf3a0702..3389ecb014 100644 --- a/OpenSim/Framework/Watchdog.cs +++ b/OpenSim/Framework/Watchdog.cs @@ -127,7 +127,7 @@ namespace OpenSim.Framework m_threads.Add(threadInfo.Thread.ManagedThreadId, threadInfo); } - private static bool RemoveThread(int threadID) + public static bool RemoveThread(int threadID) { lock (m_threads) return m_threads.Remove(threadID); diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index d915807aa7..deeb81724f 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1093,6 +1093,7 @@ namespace OpenSim.Region.Framework.Scenes { m_log.ErrorFormat("[SCENE]: Restarting heartbeat thread because it hasn't reported in in region {0}", RegionInfo.RegionName); HeartbeatThread.Abort(); + Watchdog.RemoveThread(HeartbeatThread.ManagedThreadId); HeartbeatThread = null; } m_lastUpdate = Util.EnvironmentTickCount(); @@ -4801,7 +4802,7 @@ namespace OpenSim.Region.Framework.Scenes if (m_firstHeartbeat) return; - if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 2000) + if (Util.EnvironmentTickCountSubtract(m_lastUpdate) > 10000) StartTimer(); } diff --git a/OpenSim/Region/Framework/Scenes/SceneViewer.cs b/OpenSim/Region/Framework/Scenes/SceneViewer.cs index b44a0100a4..40a73a9d4c 100644 --- a/OpenSim/Region/Framework/Scenes/SceneViewer.cs +++ b/OpenSim/Region/Framework/Scenes/SceneViewer.cs @@ -106,7 +106,7 @@ namespace OpenSim.Region.Framework.Scenes g.ScheduleFullUpdateToAvatar(m_presence); } - while (m_partsUpdateQueue.Count > 0) + while (m_partsUpdateQueue.Count != null && m_partsUpdateQueue.Count > 0) { SceneObjectPart part = m_partsUpdateQueue.Dequeue(); From 32cc569b008e4d847530577081528c7baf51d8bb Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 22 Dec 2010 13:45:21 +0100 Subject: [PATCH 11/14] Fix up some locking issues in task inventory. Don't use any prior versions in production! --- OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index da1b983d49..9412e093e1 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -959,6 +959,7 @@ namespace OpenSim.Region.Framework.Scenes if (m_inventorySerial == 0) // No inventory { client.SendTaskInventory(m_part.UUID, 0, new byte[0]); + Items.LockItemsForRead(false); return; } @@ -971,6 +972,7 @@ namespace OpenSim.Region.Framework.Scenes { xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); + Items.LockItemsForRead(false); return; } } From 990e73d7cb666fa761d0ba981721764963ade94a Mon Sep 17 00:00:00 2001 From: Melanie Date: Wed, 22 Dec 2010 17:33:06 +0000 Subject: [PATCH 12/14] Fix a broken format on an error message. Also replace yet another e.Message with e.ToString(). e.Message is USELESS, it doesn't tell us what happened where, we should use e.ToSTring() everywhere --- .../CoreModules/Avatar/InstantMessage/MessageTransferModule.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs index fdc48c6b69..21a61a79a9 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs @@ -621,8 +621,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage } catch (WebException e) { - m_log.ErrorFormat("[GRID INSTANT MESSAGE]: Error sending message to {0}} the host didn't respond ({2})", - reginfo.ServerURI, e.Message); + m_log.ErrorFormat("[GRID INSTANT MESSAGE]: Error sending message to {0} the host didn't respond " + e.ToString(), reginfo.ServerURI.ToString()); } return false; From 2d8f448322971061a148cf20cda7946893714938 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 22 Dec 2010 10:42:29 -0800 Subject: [PATCH 13/14] Fixed wrong argument cardinality in debug message. --- .../CoreModules/Avatar/InstantMessage/MessageTransferModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs index fdc48c6b69..7ca6be54b7 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/MessageTransferModule.cs @@ -621,7 +621,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage } catch (WebException e) { - m_log.ErrorFormat("[GRID INSTANT MESSAGE]: Error sending message to {0}} the host didn't respond ({2})", + m_log.ErrorFormat("[GRID INSTANT MESSAGE]: Error sending message to {0}} the host didn't respond ({1})", reginfo.ServerURI, e.Message); } From 862da9a55fe94ae70a5bba306139b5eb1bb7f6f7 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 22 Dec 2010 17:55:58 -0800 Subject: [PATCH 14/14] Added a counter to NewFiles in Xfers to account for simultaneous object inventory requests, which apparently are happening and may cause race conditions if the file name is removed after the first transfer. --- .../CoreModules/Agent/Xfer/XferModule.cs | 58 ++++++++++++++----- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs b/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs index 57875dac26..c5a6e628bd 100644 --- a/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs +++ b/OpenSim/Region/CoreModules/Agent/Xfer/XferModule.cs @@ -40,8 +40,8 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer private Scene m_scene; private Dictionary Requests = new Dictionary(); private List RequestTime = new List(); - public Dictionary NewFiles = new Dictionary(); - public Dictionary Transfers = new Dictionary(); + private Dictionary NewFiles = new Dictionary(); + private Dictionary Transfers = new Dictionary(); public struct XferRequest @@ -51,6 +51,12 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer public string fileName; public DateTime timeStamp; } + + private class FileData + { + public byte[] Data; + public int Count; + } #region IRegionModule Members @@ -89,21 +95,22 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer lock (NewFiles) { if (NewFiles.ContainsKey(fileName)) - { - NewFiles[fileName] = data; - } + NewFiles[fileName].Count++; else { - NewFiles.Add(fileName, data); + FileData fd = new FileData(); + fd.Count = 1; + fd.Data = data; + NewFiles.Add(fileName, fd); } } - string filename = string.Empty; - if (Requests.ContainsKey(fileName)) - { - RequestXfer(Requests[fileName].remoteClient, Requests[fileName].xferID, fileName); - Requests.Remove(fileName); - } + // This should not be here + //if (Requests.ContainsKey(fileName)) + //{ + // RequestXfer(Requests[fileName].remoteClient, Requests[fileName].xferID, fileName); + // Requests.Remove(fileName); + //} return true; } @@ -135,6 +142,7 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer ulong zxferid = RequestTime[0].xferID; remoteClient.SendAbortXferPacket(zxferid); RemoveXferData(zxferid); + RemoveOrDecrement(fileName); } } @@ -142,16 +150,19 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer { if (!Transfers.ContainsKey(xferID)) { - byte[] fileData = NewFiles[fileName]; + byte[] fileData = NewFiles[fileName].Data; XferDownLoad transaction = new XferDownLoad(fileName, fileData, xferID, remoteClient); Transfers.Add(xferID, transaction); - NewFiles.Remove(fileName); if (transaction.StartSend()) { RemoveXferData(xferID); } + + // The transaction for this file is either complete or on its way + RemoveOrDecrement(fileName); + } } else @@ -195,6 +206,7 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer { { RemoveXferData(xferID); + RemoveOrDecrement(dl.FileName); } } else @@ -226,8 +238,6 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer xferItem.DataPointer = 0; // If the abort comes in - if (NewFiles.ContainsKey(xferItem.FileName)) - NewFiles.Remove(xferItem.FileName); if (Requests.ContainsKey(xferItem.FileName)) Requests.Remove(xferItem.FileName); @@ -239,10 +249,26 @@ namespace OpenSim.Region.CoreModules.Agent.Xfer { lock (NewFiles) { + if (Transfers.ContainsKey(xferID)) + RemoveOrDecrement(Transfers[xferID].FileName); + RemoveXferData(xferID); } } + private void RemoveOrDecrement(string fileName) + { + // NewFiles must be locked + + if (NewFiles.ContainsKey(fileName)) + { + if (NewFiles[fileName].Count == 1) + NewFiles.Remove(fileName); + else + NewFiles[fileName].Count--; + } + } + #region Nested type: XferDownLoad public class XferDownLoad