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 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);