aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs')
-rw-r--r--OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs127
1 files changed, 105 insertions, 22 deletions
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
index a5dcdcc..4cedfe6 100644
--- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
+++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs
@@ -48,11 +48,21 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
48 }; 48 };
49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
50 50
51 /// <summary>
52 /// Reference to the object that holds this uploader. Used to remove ourselves from it's list if we
53 /// are performing a delayed update.
54 /// </summary>
55 AgentAssetTransactions m_transactions;
56
51 private AssetBase m_asset; 57 private AssetBase m_asset;
52 private UUID InventFolder = UUID.Zero; 58 private UUID InventFolder = UUID.Zero;
53 private sbyte invType = 0; 59 private sbyte invType = 0;
60
54 private bool m_createItem = false; 61 private bool m_createItem = false;
55 private uint m_createItemCallback = 0; 62 private uint m_createItemCallback = 0;
63 private bool m_updateItem = false;
64 private InventoryItemBase m_updateItemData;
65
56 private string m_description = String.Empty; 66 private string m_description = String.Empty;
57 private bool m_dumpAssetToFile; 67 private bool m_dumpAssetToFile;
58 private bool m_finished = false; 68 private bool m_finished = false;
@@ -67,9 +77,11 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
67 public ulong XferID; 77 public ulong XferID;
68 private Scene m_Scene; 78 private Scene m_Scene;
69 79
70 public AssetXferUploader(Scene scene, bool dumpAssetToFile) 80 public AssetXferUploader(AgentAssetTransactions transactions, Scene scene, UUID assetID, bool dumpAssetToFile)
71 { 81 {
82 m_transactions = transactions;
72 m_Scene = scene; 83 m_Scene = scene;
84 m_asset = new AssetBase() { FullID = assetID };
73 m_dumpAssetToFile = dumpAssetToFile; 85 m_dumpAssetToFile = dumpAssetToFile;
74 } 86 }
75 87
@@ -82,6 +94,10 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
82 /// <returns>True if the transfer is complete, false otherwise or if the xferID was not valid</returns> 94 /// <returns>True if the transfer is complete, false otherwise or if the xferID was not valid</returns>
83 public bool HandleXferPacket(ulong xferID, uint packetID, byte[] data) 95 public bool HandleXferPacket(ulong xferID, uint packetID, byte[] data)
84 { 96 {
97// m_log.DebugFormat(
98// "[ASSET XFER UPLOADER]: Received packet {0} for xfer {1} (data length {2})",
99// packetID, xferID, data.Length);
100
85 if (XferID == xferID) 101 if (XferID == xferID)
86 { 102 {
87 if (m_asset.Data.Length > 1) 103 if (m_asset.Data.Length > 1)
@@ -116,16 +132,20 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
116 /// <param name="xferID"></param> 132 /// <param name="xferID"></param>
117 /// <param name="packetID"></param> 133 /// <param name="packetID"></param>
118 /// <param name="data"></param> 134 /// <param name="data"></param>
119 /// <returns>True if the transfer is complete, false otherwise</returns> 135 public void Initialise(IClientAPI remoteClient, UUID assetID,
120 public bool Initialise(IClientAPI remoteClient, UUID assetID,
121 UUID transaction, sbyte type, byte[] data, bool storeLocal, 136 UUID transaction, sbyte type, byte[] data, bool storeLocal,
122 bool tempFile) 137 bool tempFile)
123 { 138 {
139// m_log.DebugFormat(
140// "[ASSET XFER UPLOADER]: Initialised xfer from {0}, asset {1}, transaction {2}, type {3}, storeLocal {4}, tempFile {5}, already received data length {6}",
141// remoteClient.Name, assetID, transaction, type, storeLocal, tempFile, data.Length);
142
124 ourClient = remoteClient; 143 ourClient = remoteClient;
125 m_asset = new AssetBase(assetID, "blank", type, 144 m_asset.Name = "blank";
126 remoteClient.AgentId.ToString());
127 m_asset.Data = data;
128 m_asset.Description = "empty"; 145 m_asset.Description = "empty";
146 m_asset.Type = type;
147 m_asset.CreatorID = remoteClient.AgentId.ToString();
148 m_asset.Data = data;
129 m_asset.Local = storeLocal; 149 m_asset.Local = storeLocal;
130 m_asset.Temporary = tempFile; 150 m_asset.Temporary = tempFile;
131 151
@@ -135,21 +155,22 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
135 if (m_asset.Data.Length > 2) 155 if (m_asset.Data.Length > 2)
136 { 156 {
137 SendCompleteMessage(); 157 SendCompleteMessage();
138 return true;
139 } 158 }
140 else 159 else
141 { 160 {
142 RequestStartXfer(); 161 RequestStartXfer();
143 } 162 }
144
145 return false;
146 } 163 }
147 164
148 protected void RequestStartXfer() 165 protected void RequestStartXfer()
149 { 166 {
150 XferID = Util.GetNextXferID(); 167 XferID = Util.GetNextXferID();
151 ourClient.SendXferRequest(XferID, m_asset.Type, m_asset.FullID, 168
152 0, new byte[0]); 169// m_log.DebugFormat(
170// "[ASSET XFER UPLOADER]: Requesting Xfer of asset {0}, type {1}, transfer id {2} from {3}",
171// m_asset.FullID, m_asset.Type, XferID, ourClient.Name);
172
173 ourClient.SendXferRequest(XferID, m_asset.Type, m_asset.FullID, 0, new byte[0]);
153 } 174 }
154 175
155 protected void SendCompleteMessage() 176 protected void SendCompleteMessage()
@@ -157,18 +178,32 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
157 ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, 178 ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true,
158 m_asset.FullID); 179 m_asset.FullID);
159 180
160 m_finished = true; 181 // We must lock in order to avoid a race with a separate thread dealing with an inventory item or create
161 if (m_createItem) 182 // message from other client UDP.
183 lock (this)
162 { 184 {
163 DoCreateItem(m_createItemCallback); 185 m_finished = true;
164 } 186 if (m_createItem)
165 else if (m_storeLocal) 187 {
166 { 188 DoCreateItem(m_createItemCallback);
167 m_Scene.AssetService.Store(m_asset); 189 }
190 else if (m_updateItem)
191 {
192 StoreAssetForItemUpdate(m_updateItemData);
193
194 // Remove ourselves from the list of transactions if completion was delayed until the transaction
195 // was complete.
196 // TODO: Should probably do the same for create item.
197 m_transactions.RemoveXferUploader(TransactionID);
198 }
199 else if (m_storeLocal)
200 {
201 m_Scene.AssetService.Store(m_asset);
202 }
168 } 203 }
169 204
170 m_log.DebugFormat( 205 m_log.DebugFormat(
171 "[ASSET TRANSACTIONS]: Uploaded asset {0} for transaction {1}", 206 "[ASSET XFER UPLOADER]: Uploaded asset {0} for transaction {1}",
172 m_asset.FullID, TransactionID); 207 m_asset.FullID, TransactionID);
173 208
174 if (m_dumpAssetToFile) 209 if (m_dumpAssetToFile)
@@ -214,18 +249,66 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction
214 m_asset.Description = description; 249 m_asset.Description = description;
215 m_asset.Type = type; 250 m_asset.Type = type;
216 251
252 // We must lock to avoid a race with a separate thread uploading the asset.
253 lock (this)
254 {
255 if (m_finished)
256 {
257 DoCreateItem(callbackID);
258 }
259 else
260 {
261 m_createItem = true; //set flag so the inventory item is created when upload is complete
262 m_createItemCallback = callbackID;
263 }
264 }
265 }
266 }
267
268 public void RequestUpdateInventoryItem(IClientAPI remoteClient, UUID transactionID, InventoryItemBase item)
269 {
270 // We must lock to avoid a race with a separate thread uploading the asset.
271 lock (this)
272 {
273 m_asset.Name = item.Name;
274 m_asset.Description = item.Description;
275 m_asset.Type = (sbyte)item.AssetType;
276
277 // We must always store the item at this point even if the asset hasn't finished uploading, in order
278 // to avoid a race condition when the appearance module retrieves the item to set the asset id in
279 // the AvatarAppearance structure.
280 item.AssetID = m_asset.FullID;
281 m_Scene.InventoryService.UpdateItem(item);
282
217 if (m_finished) 283 if (m_finished)
218 { 284 {
219 DoCreateItem(callbackID); 285 StoreAssetForItemUpdate(item);
220 } 286 }
221 else 287 else
222 { 288 {
223 m_createItem = true; //set flag so the inventory item is created when upload is complete 289// m_log.DebugFormat(
224 m_createItemCallback = callbackID; 290// "[ASSET XFER UPLOADER]: Holding update inventory item request {0} for {1} pending completion of asset xfer for transaction {2}",
291// item.Name, remoteClient.Name, transactionID);
292
293 m_updateItem = true;
294 m_updateItemData = item;
225 } 295 }
226 } 296 }
227 } 297 }
228 298
299 /// <summary>
300 /// Store the asset for the given item.
301 /// </summary>
302 /// <param name="item"></param>
303 private void StoreAssetForItemUpdate(InventoryItemBase item)
304 {
305// m_log.DebugFormat(
306// "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}",
307// m_asset.FullID, item.Name, ourClient.Name);
308
309 m_Scene.AssetService.Store(m_asset);
310 }
311
229 private void DoCreateItem(uint callbackID) 312 private void DoCreateItem(uint callbackID)
230 { 313 {
231 ValidateAssets(); 314 ValidateAssets();