diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/Agent')
3 files changed, 238 insertions, 82 deletions
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs index 9d8082b..eed7cd5 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs | |||
@@ -41,14 +41,13 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
41 | /// </summary> | 41 | /// </summary> |
42 | public class AgentAssetTransactions | 42 | public class AgentAssetTransactions |
43 | { | 43 | { |
44 | // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 44 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
45 | 45 | ||
46 | // Fields | 46 | // Fields |
47 | private bool m_dumpAssetsToFile; | 47 | private bool m_dumpAssetsToFile; |
48 | private Scene m_Scene; | 48 | private Scene m_Scene; |
49 | public UUID UserID; | 49 | private UUID UserID; |
50 | public Dictionary<UUID, AssetXferUploader> XferUploaders = | 50 | private Dictionary<UUID, AssetXferUploader> XferUploaders = new Dictionary<UUID, AssetXferUploader>(); |
51 | new Dictionary<UUID, AssetXferUploader>(); | ||
52 | 51 | ||
53 | // Methods | 52 | // Methods |
54 | public AgentAssetTransactions(UUID agentID, Scene scene, | 53 | public AgentAssetTransactions(UUID agentID, Scene scene, |
@@ -59,36 +58,94 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
59 | m_dumpAssetsToFile = dumpAssetsToFile; | 58 | m_dumpAssetsToFile = dumpAssetsToFile; |
60 | } | 59 | } |
61 | 60 | ||
62 | public AssetXferUploader RequestXferUploader(UUID transactionID) | 61 | /// <summary> |
62 | /// Return a xfer uploader if one does not already exist. | ||
63 | /// </summary> | ||
64 | /// <param name="transactionID"></param> | ||
65 | /// <param name="assetID"> | ||
66 | /// We must transfer the new asset ID into the uploader on creation, otherwise | ||
67 | /// we can see race conditions with other threads which can retrieve an item before it is updated with the new | ||
68 | /// asset id. | ||
69 | /// </param> | ||
70 | /// <returns> | ||
71 | /// The xfer uploader requested. Null if one is already in existence. | ||
72 | /// FIXME: This is a bizarre thing to do, and is probably meant to signal an error condition if multiple | ||
73 | /// transfers are made. Needs to be corrected. | ||
74 | /// </returns> | ||
75 | public AssetXferUploader RequestXferUploader(UUID transactionID, UUID assetID) | ||
63 | { | 76 | { |
64 | if (!XferUploaders.ContainsKey(transactionID)) | 77 | lock (XferUploaders) |
65 | { | 78 | { |
66 | AssetXferUploader uploader = new AssetXferUploader(m_Scene, | 79 | if (!XferUploaders.ContainsKey(transactionID)) |
67 | m_dumpAssetsToFile); | ||
68 | |||
69 | lock (XferUploaders) | ||
70 | { | 80 | { |
81 | AssetXferUploader uploader = new AssetXferUploader(this, m_Scene, assetID, m_dumpAssetsToFile); | ||
82 | |||
83 | // m_log.DebugFormat( | ||
84 | // "[AGENT ASSETS TRANSACTIONS]: Adding asset xfer uploader {0} since it didn't previously exist", transactionID); | ||
85 | |||
71 | XferUploaders.Add(transactionID, uploader); | 86 | XferUploaders.Add(transactionID, uploader); |
72 | } | ||
73 | 87 | ||
74 | return uploader; | 88 | return uploader; |
89 | } | ||
75 | } | 90 | } |
91 | |||
92 | m_log.WarnFormat("[AGENT ASSETS TRANSACTIONS]: Ignoring request for asset xfer uploader {0} since it already exists", transactionID); | ||
93 | |||
76 | return null; | 94 | return null; |
77 | } | 95 | } |
78 | 96 | ||
79 | public void HandleXfer(ulong xferID, uint packetID, byte[] data) | 97 | public void HandleXfer(ulong xferID, uint packetID, byte[] data) |
80 | { | 98 | { |
99 | AssetXferUploader foundUploader = null; | ||
100 | |||
81 | lock (XferUploaders) | 101 | lock (XferUploaders) |
82 | { | 102 | { |
83 | foreach (AssetXferUploader uploader in XferUploaders.Values) | 103 | foreach (AssetXferUploader uploader in XferUploaders.Values) |
84 | { | 104 | { |
105 | // m_log.DebugFormat( | ||
106 | // "[AGENT ASSETS TRANSACTIONS]: In HandleXfer, inspect xfer upload with xfer id {0}", | ||
107 | // uploader.XferID); | ||
108 | |||
85 | if (uploader.XferID == xferID) | 109 | if (uploader.XferID == xferID) |
86 | { | 110 | { |
87 | uploader.HandleXferPacket(xferID, packetID, data); | 111 | foundUploader = uploader; |
88 | break; | 112 | break; |
89 | } | 113 | } |
90 | } | 114 | } |
91 | } | 115 | } |
116 | |||
117 | if (foundUploader != null) | ||
118 | { | ||
119 | // m_log.DebugFormat( | ||
120 | // "[AGENT ASSETS TRANSACTIONS]: Found xfer uploader for xfer id {0}, packet id {1}, data length {2}", | ||
121 | // xferID, packetID, data.Length); | ||
122 | |||
123 | foundUploader.HandleXferPacket(xferID, packetID, data); | ||
124 | } | ||
125 | else | ||
126 | { | ||
127 | m_log.ErrorFormat( | ||
128 | "[AGENT ASSET TRANSACTIONS]: Could not find uploader for xfer id {0}, packet id {1}, data length {2}", | ||
129 | xferID, packetID, data.Length); | ||
130 | } | ||
131 | } | ||
132 | |||
133 | public bool RemoveXferUploader(UUID transactionID) | ||
134 | { | ||
135 | lock (XferUploaders) | ||
136 | { | ||
137 | bool removed = XferUploaders.Remove(transactionID); | ||
138 | |||
139 | if (!removed) | ||
140 | m_log.WarnFormat( | ||
141 | "[AGENT ASSET TRANSACTIONS]: Received request to remove xfer uploader with transaction ID {0} but none found", | ||
142 | transactionID); | ||
143 | // else | ||
144 | // m_log.DebugFormat( | ||
145 | // "[AGENT ASSET TRANSACTIONS]: Removed xfer uploader with transaction ID {0}", transactionID); | ||
146 | |||
147 | return removed; | ||
148 | } | ||
92 | } | 149 | } |
93 | 150 | ||
94 | public void RequestCreateInventoryItem(IClientAPI remoteClient, | 151 | public void RequestCreateInventoryItem(IClientAPI remoteClient, |
@@ -96,16 +153,24 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
96 | string description, string name, sbyte invType, | 153 | string description, string name, sbyte invType, |
97 | sbyte type, byte wearableType, uint nextOwnerMask) | 154 | sbyte type, byte wearableType, uint nextOwnerMask) |
98 | { | 155 | { |
99 | if (XferUploaders.ContainsKey(transactionID)) | 156 | AssetXferUploader uploader = null; |
157 | |||
158 | lock (XferUploaders) | ||
100 | { | 159 | { |
101 | XferUploaders[transactionID].RequestCreateInventoryItem( | 160 | if (XferUploaders.ContainsKey(transactionID)) |
102 | remoteClient, transactionID, folderID, | 161 | uploader = XferUploaders[transactionID]; |
103 | callbackID, description, name, invType, type, | ||
104 | wearableType, nextOwnerMask); | ||
105 | } | 162 | } |
106 | } | ||
107 | |||
108 | 163 | ||
164 | if (uploader != null) | ||
165 | uploader.RequestCreateInventoryItem( | ||
166 | remoteClient, transactionID, folderID, | ||
167 | callbackID, description, name, invType, type, | ||
168 | wearableType, nextOwnerMask); | ||
169 | else | ||
170 | m_log.ErrorFormat( | ||
171 | "[AGENT ASSET TRANSACTIONS]: Could not find uploader with transaction ID {0} when handling request to create inventory item {1} from {2}", | ||
172 | transactionID, name, remoteClient.Name); | ||
173 | } | ||
109 | 174 | ||
110 | /// <summary> | 175 | /// <summary> |
111 | /// Get an uploaded asset. If the data is successfully retrieved, | 176 | /// Get an uploaded asset. If the data is successfully retrieved, |
@@ -113,19 +178,18 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
113 | /// </summary> | 178 | /// </summary> |
114 | /// <param name="transactionID"></param> | 179 | /// <param name="transactionID"></param> |
115 | /// <returns>The asset if the upload has completed, null if it has not.</returns> | 180 | /// <returns>The asset if the upload has completed, null if it has not.</returns> |
116 | public AssetBase GetTransactionAsset(UUID transactionID) | 181 | private AssetBase GetTransactionAsset(UUID transactionID) |
117 | { | 182 | { |
118 | if (XferUploaders.ContainsKey(transactionID)) | 183 | lock (XferUploaders) |
119 | { | 184 | { |
120 | AssetXferUploader uploader = XferUploaders[transactionID]; | 185 | if (XferUploaders.ContainsKey(transactionID)) |
121 | AssetBase asset = uploader.GetAssetData(); | ||
122 | |||
123 | lock (XferUploaders) | ||
124 | { | 186 | { |
125 | XferUploaders.Remove(transactionID); | 187 | AssetXferUploader uploader = XferUploaders[transactionID]; |
126 | } | 188 | AssetBase asset = uploader.GetAssetData(); |
189 | RemoveXferUploader(transactionID); | ||
127 | 190 | ||
128 | return asset; | 191 | return asset; |
192 | } | ||
129 | } | 193 | } |
130 | 194 | ||
131 | return null; | 195 | return null; |
@@ -135,7 +199,15 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
135 | SceneObjectPart part, UUID transactionID, | 199 | SceneObjectPart part, UUID transactionID, |
136 | TaskInventoryItem item) | 200 | TaskInventoryItem item) |
137 | { | 201 | { |
138 | if (XferUploaders.ContainsKey(transactionID)) | 202 | AssetXferUploader uploader = null; |
203 | |||
204 | lock (XferUploaders) | ||
205 | { | ||
206 | if (XferUploaders.ContainsKey(transactionID)) | ||
207 | uploader = XferUploaders[transactionID]; | ||
208 | } | ||
209 | |||
210 | if (uploader != null) | ||
139 | { | 211 | { |
140 | AssetBase asset = GetTransactionAsset(transactionID); | 212 | AssetBase asset = GetTransactionAsset(transactionID); |
141 | 213 | ||
@@ -161,28 +233,34 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
161 | m_Scene.AssetService.Store(asset); | 233 | m_Scene.AssetService.Store(asset); |
162 | } | 234 | } |
163 | } | 235 | } |
236 | else | ||
237 | { | ||
238 | m_log.ErrorFormat( | ||
239 | "[AGENT ASSET TRANSACTIONS]: Could not find uploader with transaction ID {0} when handling request to update task inventory item {1} in {2}", | ||
240 | transactionID, item.Name, part.Name); | ||
241 | } | ||
164 | } | 242 | } |
165 | 243 | ||
166 | public void RequestUpdateInventoryItem(IClientAPI remoteClient, | 244 | public void RequestUpdateInventoryItem(IClientAPI remoteClient, |
167 | UUID transactionID, InventoryItemBase item) | 245 | UUID transactionID, InventoryItemBase item) |
168 | { | 246 | { |
169 | if (XferUploaders.ContainsKey(transactionID)) | 247 | AssetXferUploader uploader = null; |
170 | { | ||
171 | AssetBase asset = GetTransactionAsset(transactionID); | ||
172 | 248 | ||
173 | if (asset != null) | 249 | lock (XferUploaders) |
174 | { | 250 | { |
175 | asset.FullID = UUID.Random(); | 251 | if (XferUploaders.ContainsKey(transactionID)) |
176 | asset.Name = item.Name; | 252 | uploader = XferUploaders[transactionID]; |
177 | asset.Description = item.Description; | 253 | } |
178 | asset.Type = (sbyte)item.AssetType; | ||
179 | item.AssetID = asset.FullID; | ||
180 | |||
181 | m_Scene.AssetService.Store(asset); | ||
182 | 254 | ||
183 | IInventoryService invService = m_Scene.InventoryService; | 255 | if (uploader != null) |
184 | invService.UpdateItem(item); | 256 | { |
185 | } | 257 | uploader.RequestUpdateInventoryItem(remoteClient, transactionID, item); |
258 | } | ||
259 | else | ||
260 | { | ||
261 | m_log.ErrorFormat( | ||
262 | "[AGENT ASSET TRANSACTIONS]: Could not find uploader with transaction ID {0} when handling request to update inventory item {1} for {2}", | ||
263 | transactionID, item.Name, remoteClient.Name); | ||
186 | } | 264 | } |
187 | } | 265 | } |
188 | } | 266 | } |
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs index 82558de..a28d5d7 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs | |||
@@ -172,11 +172,12 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
172 | /// <summary> | 172 | /// <summary> |
173 | /// Update an inventory item with data that has been received through a | 173 | /// Update an inventory item with data that has been received through a |
174 | /// transaction. | 174 | /// transaction. |
175 | /// | 175 | /// </summary> |
176 | /// <remarks> | ||
176 | /// This is called when clothing or body parts are updated (for | 177 | /// This is called when clothing or body parts are updated (for |
177 | /// instance, with new textures or colours). It may also be called in | 178 | /// instance, with new textures or colours). It may also be called in |
178 | /// other situations. | 179 | /// other situations. |
179 | /// </summary> | 180 | /// </remarks> |
180 | /// <param name="remoteClient"></param> | 181 | /// <param name="remoteClient"></param> |
181 | /// <param name="transactionID"></param> | 182 | /// <param name="transactionID"></param> |
182 | /// <param name="item"></param> | 183 | /// <param name="item"></param> |
@@ -184,14 +185,12 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
184 | UUID transactionID, InventoryItemBase item) | 185 | UUID transactionID, InventoryItemBase item) |
185 | { | 186 | { |
186 | // m_log.DebugFormat( | 187 | // m_log.DebugFormat( |
187 | // "[TRANSACTIONS MANAGER] Called HandleItemUpdateFromTransaction with item {0}", | 188 | // "[ASSET TRANSACTION MODULE]: Called HandleItemUpdateFromTransaction with item {0}", |
188 | // item.Name); | 189 | // item.Name); |
189 | 190 | ||
190 | AgentAssetTransactions transactions = | 191 | AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); |
191 | GetUserTransactions(remoteClient.AgentId); | ||
192 | 192 | ||
193 | transactions.RequestUpdateInventoryItem(remoteClient, | 193 | transactions.RequestUpdateInventoryItem(remoteClient, transactionID, item); |
194 | transactionID, item); | ||
195 | } | 194 | } |
196 | 195 | ||
197 | /// <summary> | 196 | /// <summary> |
@@ -255,11 +254,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
255 | } | 254 | } |
256 | } | 255 | } |
257 | 256 | ||
258 | AgentAssetTransactions transactions = | 257 | AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); |
259 | GetUserTransactions(remoteClient.AgentId); | 258 | AssetXferUploader uploader = transactions.RequestXferUploader(transaction, assetID); |
260 | |||
261 | AssetXferUploader uploader = | ||
262 | transactions.RequestXferUploader(transaction); | ||
263 | 259 | ||
264 | if (uploader != null) | 260 | if (uploader != null) |
265 | { | 261 | { |
@@ -279,9 +275,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
279 | public void HandleXfer(IClientAPI remoteClient, ulong xferID, | 275 | public void HandleXfer(IClientAPI remoteClient, ulong xferID, |
280 | uint packetID, byte[] data) | 276 | uint packetID, byte[] data) |
281 | { | 277 | { |
282 | //m_log.Debug("xferID: " + xferID + " packetID: " + packetID + " data!"); | 278 | // m_log.Debug("xferID: " + xferID + " packetID: " + packetID + " data length " + data.Length); |
283 | AgentAssetTransactions transactions = | 279 | AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); |
284 | GetUserTransactions(remoteClient.AgentId); | ||
285 | 280 | ||
286 | transactions.HandleXfer(xferID, packetID, data); | 281 | transactions.HandleXfer(xferID, packetID, data); |
287 | } | 282 | } |
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs index a7929ba..ec4dfd0 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs | |||
@@ -40,11 +40,21 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
40 | { | 40 | { |
41 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 41 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
42 | 42 | ||
43 | /// <summary> | ||
44 | /// Reference to the object that holds this uploader. Used to remove ourselves from it's list if we | ||
45 | /// are performing a delayed update. | ||
46 | /// </summary> | ||
47 | AgentAssetTransactions m_transactions; | ||
48 | |||
43 | private AssetBase m_asset; | 49 | private AssetBase m_asset; |
44 | private UUID InventFolder = UUID.Zero; | 50 | private UUID InventFolder = UUID.Zero; |
45 | private sbyte invType = 0; | 51 | private sbyte invType = 0; |
52 | |||
46 | private bool m_createItem = false; | 53 | private bool m_createItem = false; |
47 | private uint m_createItemCallback = 0; | 54 | private uint m_createItemCallback = 0; |
55 | private bool m_updateItem = false; | ||
56 | private InventoryItemBase m_updateItemData; | ||
57 | |||
48 | private string m_description = String.Empty; | 58 | private string m_description = String.Empty; |
49 | private bool m_dumpAssetToFile; | 59 | private bool m_dumpAssetToFile; |
50 | private bool m_finished = false; | 60 | private bool m_finished = false; |
@@ -58,9 +68,11 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
58 | public ulong XferID; | 68 | public ulong XferID; |
59 | private Scene m_Scene; | 69 | private Scene m_Scene; |
60 | 70 | ||
61 | public AssetXferUploader(Scene scene, bool dumpAssetToFile) | 71 | public AssetXferUploader(AgentAssetTransactions transactions, Scene scene, UUID assetID, bool dumpAssetToFile) |
62 | { | 72 | { |
73 | m_transactions = transactions; | ||
63 | m_Scene = scene; | 74 | m_Scene = scene; |
75 | m_asset = new AssetBase() { FullID = assetID }; | ||
64 | m_dumpAssetToFile = dumpAssetToFile; | 76 | m_dumpAssetToFile = dumpAssetToFile; |
65 | } | 77 | } |
66 | 78 | ||
@@ -73,6 +85,10 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
73 | /// <returns>True if the transfer is complete, false otherwise or if the xferID was not valid</returns> | 85 | /// <returns>True if the transfer is complete, false otherwise or if the xferID was not valid</returns> |
74 | public bool HandleXferPacket(ulong xferID, uint packetID, byte[] data) | 86 | public bool HandleXferPacket(ulong xferID, uint packetID, byte[] data) |
75 | { | 87 | { |
88 | // m_log.DebugFormat( | ||
89 | // "[ASSET XFER UPLOADER]: Received packet {0} for xfer {1} (data length {2})", | ||
90 | // packetID, xferID, data.Length); | ||
91 | |||
76 | if (XferID == xferID) | 92 | if (XferID == xferID) |
77 | { | 93 | { |
78 | if (m_asset.Data.Length > 1) | 94 | if (m_asset.Data.Length > 1) |
@@ -107,16 +123,20 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
107 | /// <param name="xferID"></param> | 123 | /// <param name="xferID"></param> |
108 | /// <param name="packetID"></param> | 124 | /// <param name="packetID"></param> |
109 | /// <param name="data"></param> | 125 | /// <param name="data"></param> |
110 | /// <returns>True if the transfer is complete, false otherwise</returns> | 126 | public void Initialise(IClientAPI remoteClient, UUID assetID, |
111 | public bool Initialise(IClientAPI remoteClient, UUID assetID, | ||
112 | UUID transaction, sbyte type, byte[] data, bool storeLocal, | 127 | UUID transaction, sbyte type, byte[] data, bool storeLocal, |
113 | bool tempFile) | 128 | bool tempFile) |
114 | { | 129 | { |
130 | // m_log.DebugFormat( | ||
131 | // "[ASSET XFER UPLOADER]: Initialised xfer from {0}, asset {1}, transaction {2}, type {3}, storeLocal {4}, tempFile {5}, already received data length {6}", | ||
132 | // remoteClient.Name, assetID, transaction, type, storeLocal, tempFile, data.Length); | ||
133 | |||
115 | ourClient = remoteClient; | 134 | ourClient = remoteClient; |
116 | m_asset = new AssetBase(assetID, "blank", type, | 135 | m_asset.Name = "blank"; |
117 | remoteClient.AgentId.ToString()); | ||
118 | m_asset.Data = data; | ||
119 | m_asset.Description = "empty"; | 136 | m_asset.Description = "empty"; |
137 | m_asset.Type = type; | ||
138 | m_asset.CreatorID = remoteClient.AgentId.ToString(); | ||
139 | m_asset.Data = data; | ||
120 | m_asset.Local = storeLocal; | 140 | m_asset.Local = storeLocal; |
121 | m_asset.Temporary = tempFile; | 141 | m_asset.Temporary = tempFile; |
122 | 142 | ||
@@ -126,21 +146,22 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
126 | if (m_asset.Data.Length > 2) | 146 | if (m_asset.Data.Length > 2) |
127 | { | 147 | { |
128 | SendCompleteMessage(); | 148 | SendCompleteMessage(); |
129 | return true; | ||
130 | } | 149 | } |
131 | else | 150 | else |
132 | { | 151 | { |
133 | RequestStartXfer(); | 152 | RequestStartXfer(); |
134 | } | 153 | } |
135 | |||
136 | return false; | ||
137 | } | 154 | } |
138 | 155 | ||
139 | protected void RequestStartXfer() | 156 | protected void RequestStartXfer() |
140 | { | 157 | { |
141 | XferID = Util.GetNextXferID(); | 158 | XferID = Util.GetNextXferID(); |
142 | ourClient.SendXferRequest(XferID, m_asset.Type, m_asset.FullID, | 159 | |
143 | 0, new byte[0]); | 160 | // m_log.DebugFormat( |
161 | // "[ASSET XFER UPLOADER]: Requesting Xfer of asset {0}, type {1}, transfer id {2} from {3}", | ||
162 | // m_asset.FullID, m_asset.Type, XferID, ourClient.Name); | ||
163 | |||
164 | ourClient.SendXferRequest(XferID, m_asset.Type, m_asset.FullID, 0, new byte[0]); | ||
144 | } | 165 | } |
145 | 166 | ||
146 | protected void SendCompleteMessage() | 167 | protected void SendCompleteMessage() |
@@ -148,18 +169,32 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
148 | ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, | 169 | ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, |
149 | m_asset.FullID); | 170 | m_asset.FullID); |
150 | 171 | ||
151 | m_finished = true; | 172 | // We must lock in order to avoid a race with a separate thread dealing with an inventory item or create |
152 | if (m_createItem) | 173 | // message from other client UDP. |
153 | { | 174 | lock (this) |
154 | DoCreateItem(m_createItemCallback); | ||
155 | } | ||
156 | else if (m_storeLocal) | ||
157 | { | 175 | { |
158 | m_Scene.AssetService.Store(m_asset); | 176 | m_finished = true; |
177 | if (m_createItem) | ||
178 | { | ||
179 | DoCreateItem(m_createItemCallback); | ||
180 | } | ||
181 | else if (m_updateItem) | ||
182 | { | ||
183 | StoreAssetForItemUpdate(m_updateItemData); | ||
184 | |||
185 | // Remove ourselves from the list of transactions if completion was delayed until the transaction | ||
186 | // was complete. | ||
187 | // TODO: Should probably do the same for create item. | ||
188 | m_transactions.RemoveXferUploader(TransactionID); | ||
189 | } | ||
190 | else if (m_storeLocal) | ||
191 | { | ||
192 | m_Scene.AssetService.Store(m_asset); | ||
193 | } | ||
159 | } | 194 | } |
160 | 195 | ||
161 | m_log.DebugFormat( | 196 | m_log.DebugFormat( |
162 | "[ASSET TRANSACTIONS]: Uploaded asset {0} for transaction {1}", | 197 | "[ASSET XFER UPLOADER]: Uploaded asset {0} for transaction {1}", |
163 | m_asset.FullID, TransactionID); | 198 | m_asset.FullID, TransactionID); |
164 | 199 | ||
165 | if (m_dumpAssetToFile) | 200 | if (m_dumpAssetToFile) |
@@ -205,18 +240,66 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
205 | m_asset.Description = description; | 240 | m_asset.Description = description; |
206 | m_asset.Type = type; | 241 | m_asset.Type = type; |
207 | 242 | ||
243 | // We must lock to avoid a race with a separate thread uploading the asset. | ||
244 | lock (this) | ||
245 | { | ||
246 | if (m_finished) | ||
247 | { | ||
248 | DoCreateItem(callbackID); | ||
249 | } | ||
250 | else | ||
251 | { | ||
252 | m_createItem = true; //set flag so the inventory item is created when upload is complete | ||
253 | m_createItemCallback = callbackID; | ||
254 | } | ||
255 | } | ||
256 | } | ||
257 | } | ||
258 | |||
259 | public void RequestUpdateInventoryItem(IClientAPI remoteClient, UUID transactionID, InventoryItemBase item) | ||
260 | { | ||
261 | // We must lock to avoid a race with a separate thread uploading the asset. | ||
262 | lock (this) | ||
263 | { | ||
264 | m_asset.Name = item.Name; | ||
265 | m_asset.Description = item.Description; | ||
266 | m_asset.Type = (sbyte)item.AssetType; | ||
267 | |||
268 | // We must always store the item at this point even if the asset hasn't finished uploading, in order | ||
269 | // to avoid a race condition when the appearance module retrieves the item to set the asset id in | ||
270 | // the AvatarAppearance structure. | ||
271 | item.AssetID = m_asset.FullID; | ||
272 | m_Scene.InventoryService.UpdateItem(item); | ||
273 | |||
208 | if (m_finished) | 274 | if (m_finished) |
209 | { | 275 | { |
210 | DoCreateItem(callbackID); | 276 | StoreAssetForItemUpdate(item); |
211 | } | 277 | } |
212 | else | 278 | else |
213 | { | 279 | { |
214 | m_createItem = true; //set flag so the inventory item is created when upload is complete | 280 | // m_log.DebugFormat( |
215 | m_createItemCallback = callbackID; | 281 | // "[ASSET XFER UPLOADER]: Holding update inventory item request {0} for {1} pending completion of asset xfer for transaction {2}", |
282 | // item.Name, remoteClient.Name, transactionID); | ||
283 | |||
284 | m_updateItem = true; | ||
285 | m_updateItemData = item; | ||
216 | } | 286 | } |
217 | } | 287 | } |
218 | } | 288 | } |
219 | 289 | ||
290 | /// <summary> | ||
291 | /// Store the asset for the given item. | ||
292 | /// </summary> | ||
293 | /// <param name="item"></param> | ||
294 | private void StoreAssetForItemUpdate(InventoryItemBase item) | ||
295 | { | ||
296 | // m_log.DebugFormat( | ||
297 | // "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}", | ||
298 | // m_asset.FullID, item.Name, ourClient.Name); | ||
299 | |||
300 | m_Scene.AssetService.Store(m_asset); | ||
301 | } | ||
302 | |||
220 | private void DoCreateItem(uint callbackID) | 303 | private void DoCreateItem(uint callbackID) |
221 | { | 304 | { |
222 | m_Scene.AssetService.Store(m_asset); | 305 | m_Scene.AssetService.Store(m_asset); |