llviewerassetstorage.cpp

Go to the documentation of this file.
00001 
00033 #include "linden_common.h"
00034 #include "llviewerprecompiledheaders.h"
00035 
00036 #include "llagent.h"
00037 #include "llviewerassetstorage.h"
00038 #include "llviewerbuild.h"
00039 #include "llvfile.h"
00040 #include "llvfs.h"
00041 
00042 LLViewerAssetStorage::LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *xfer,
00043                                                                                    LLVFS *vfs, const LLHost &upstream_host)
00044                 : LLAssetStorage(msg, xfer, vfs, upstream_host)
00045 {
00046 }
00047 
00048 
00049 LLViewerAssetStorage::LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *xfer,
00050                                                                                    LLVFS *vfs)
00051                 : LLAssetStorage(msg, xfer, vfs)
00052 {
00053 }
00054 
00055 // virtual 
00056 void LLViewerAssetStorage::storeAssetData(
00057         const LLTransactionID& tid,
00058         LLAssetType::EType asset_type,
00059         LLStoreAssetCallback callback,
00060         void* user_data,
00061         bool temp_file,
00062         bool is_priority,
00063         bool store_local,
00064         bool user_waiting,
00065         F64 timeout)
00066 {
00067         LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
00068         llinfos << "LLViewerAssetStorage::storeAssetData (legacy) " << tid << ":" << LLAssetType::lookup(asset_type)
00069                         << " ASSET_ID: " << asset_id << llendl;
00070         
00071         if (mUpstreamHost.isOk())
00072         {
00073                 if (mVFS->getExists(asset_id, asset_type))
00074                 {
00075                         // Pack data into this packet if we can fit it.
00076                         U8 buffer[MTUBYTES];
00077                         buffer[0] = 0;
00078 
00079                         LLVFile vfile(mVFS, asset_id, asset_type, LLVFile::READ);
00080                         S32 asset_size = vfile.getSize();
00081 
00082                         LLAssetRequest *req = new LLAssetRequest(asset_id, asset_type);
00083                         req->mUpCallback = callback;
00084                         req->mUserData = user_data;
00085 
00086                         if (asset_size < 1)
00087                         {
00088                                 // This can happen if there's a bug in our code or if the VFS has been corrupted.
00089                                 llwarns << "LLViewerAssetStorage::storeAssetData()  Data _should_ already be in the VFS, but it's not! " << asset_id << llendl;
00090                                 // LLAssetStorage metric: Zero size VFS
00091                                 reportMetric( asset_id, asset_type, NULL, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file didn't exist or was zero length (VFS - can't tell which)" );
00092 
00093                                 delete req;
00094                                 if (callback)
00095                                 {
00096                                         callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_FAILED, LL_EXSTAT_VFS_CORRUPT);
00097                                 }
00098                                 return;
00099                         }
00100                         else
00101                         {
00102                                 // LLAssetStorage metric: Successful Request
00103                                 S32 size = mVFS->getSize(asset_id, asset_type);
00104                                 const char *message = "Added to upload queue";
00105                                 reportMetric( asset_id, asset_type, NULL, LLUUID::null, size, MR_OKAY, __FILE__, __LINE__, message );
00106 
00107                                 if(is_priority)
00108                                 {
00109                                         mPendingUploads.push_front(req);
00110                                 }
00111                                 else
00112                                 {
00113                                         mPendingUploads.push_back(req);
00114                                 }
00115                         }
00116 
00117                         // Read the data from the VFS if it'll fit in this packet.
00118                         if (asset_size + 100 < MTUBYTES)
00119                         {
00120                                 BOOL res = vfile.read(buffer, asset_size);              /* Flawfinder: ignore */
00121                                 S32 bytes_read = res ? vfile.getLastBytesRead() : 0;
00122                                 
00123                                 if( bytes_read == asset_size )
00124                                 {
00125                                         req->mDataSentInFirstPacket = TRUE;
00126                                         //llinfos << "LLViewerAssetStorage::createAsset sending data in first packet" << llendl;
00127                                 }
00128                                 else
00129                                 {
00130                                         llwarns << "Probable corruption in VFS file, aborting store asset data" << llendl;
00131 
00132                                         // LLAssetStorage metric: VFS corrupt - bogus size
00133                                         reportMetric( asset_id, asset_type, NULL, LLUUID::null, asset_size, MR_VFS_CORRUPTION, __FILE__, __LINE__, "VFS corruption" );
00134 
00135                                         if (callback)
00136                                         {
00137                                                 callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LL_EXSTAT_VFS_CORRUPT);
00138                                         }
00139                                         return;
00140                                 }
00141                         }
00142                         else
00143                         {
00144                                 // Too big, do an xfer
00145                                 buffer[0] = 0;
00146                                 asset_size = 0;
00147                         }
00148                         mMessageSys->newMessageFast(_PREHASH_AssetUploadRequest);
00149                         mMessageSys->nextBlockFast(_PREHASH_AssetBlock);
00150                         mMessageSys->addUUIDFast(_PREHASH_TransactionID, tid);
00151                         mMessageSys->addS8Fast(_PREHASH_Type, (S8)asset_type);
00152                         mMessageSys->addBOOLFast(_PREHASH_Tempfile, temp_file);
00153                         mMessageSys->addBOOLFast(_PREHASH_StoreLocal, store_local);
00154                         mMessageSys->addBinaryDataFast( _PREHASH_AssetData, buffer, asset_size );
00155                         mMessageSys->sendReliable(mUpstreamHost);
00156                 }
00157                 else
00158                 {
00159                         llwarns << "AssetStorage: attempt to upload non-existent vfile " << asset_id << ":" << LLAssetType::lookup(asset_type) << llendl;
00160                         // LLAssetStorage metric: Zero size VFS
00161                         reportMetric( asset_id, asset_type, NULL, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file didn't exist or was zero length (VFS - can't tell which)" );
00162                         if (callback)
00163                         {
00164                                 callback(asset_id, user_data,  LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LL_EXSTAT_NONEXISTENT_FILE);
00165                         }
00166                 }
00167         }
00168         else
00169         {
00170                 llwarns << "Attempt to move asset store request upstream w/o valid upstream provider" << llendl;
00171                 // LLAssetStorage metric: Upstream provider dead
00172                 reportMetric( asset_id, asset_type, NULL, LLUUID::null, 0, MR_NO_UPSTREAM, __FILE__, __LINE__, "No upstream provider" );
00173                 if (callback)
00174                 {
00175                         callback(asset_id, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM);
00176                 }
00177         }
00178 }
00179 
00180 void LLViewerAssetStorage::storeAssetData(
00181         const char* filename,
00182         const LLTransactionID& tid,
00183         LLAssetType::EType asset_type,
00184         LLStoreAssetCallback callback,
00185         void* user_data,
00186         bool temp_file,
00187         bool is_priority,
00188         bool user_waiting,
00189         F64 timeout)
00190 {
00191 if(!filename)
00192         {
00193                 // LLAssetStorage metric: no filename
00194                 reportMetric( LLUUID::null, asset_type, "", LLUUID::null, 0, MR_VFS_CORRUPTION, __FILE__, __LINE__, "Filename missing" );
00195                 llerrs << "No filename specified" << llendl;
00196                 return;
00197         }
00198         
00199         LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
00200         llinfos << "LLViewerAssetStorage::storeAssetData (legacy)" << asset_id << ":" << LLAssetType::lookup(asset_type) << llendl;
00201 
00202         llinfos << "ASSET_ID: " << asset_id << llendl;
00203 
00204         S32 size = 0;
00205         LLFILE* fp = LLFile::fopen(filename, "rb");
00206         if (fp)
00207         {
00208                 fseek(fp, 0, SEEK_END);
00209                 size = ftell(fp);
00210                 fseek(fp, 0, SEEK_SET);
00211         }
00212         if( size )
00213         {
00214                 LLLegacyAssetRequest *legacy = new LLLegacyAssetRequest;
00215                 
00216                 legacy->mUpCallback = callback;
00217                 legacy->mUserData = user_data;
00218 
00219                 LLVFile file(mVFS, asset_id, asset_type, LLVFile::WRITE);
00220 
00221                 file.setMaxSize(size);
00222 
00223                 const S32 buf_size = 65536;
00224                 U8 copy_buf[buf_size];
00225                 while ((size = (S32)fread(copy_buf, 1, buf_size, fp)))
00226                 {
00227                         file.write(copy_buf, size);
00228                 }
00229                 fclose(fp);
00230 
00231                 // if this upload fails, the caller needs to setup a new tempfile for us
00232                 if (temp_file)
00233                 {
00234                         LLFile::remove(filename);
00235                 }
00236 
00237                 // LLAssetStorage metric: Success not needed; handled in the overloaded method here:
00238 
00239                 LLViewerAssetStorage::storeAssetData(
00240                         tid,
00241                         asset_type,
00242                         legacyStoreDataCallback,
00243                         (void**)legacy,
00244                         temp_file,
00245                         is_priority);
00246         }
00247         else // size == 0 (but previous block changes size)
00248         {
00249                 if( fp )
00250                 {
00251                         // LLAssetStorage metric: Zero size
00252                         reportMetric( asset_id, asset_type, filename, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file was zero length" );
00253                 }
00254                 else
00255                 {
00256                         // LLAssetStorage metric: Missing File
00257                         reportMetric( asset_id, asset_type, filename, LLUUID::null, 0, MR_FILE_NONEXIST, __FILE__, __LINE__, "The file didn't exist" );
00258                 }
00259                 if (callback)
00260                 {
00261                         callback(asset_id, user_data, LL_ERR_CANNOT_OPEN_FILE, LL_EXSTAT_BLOCKED_FILE);
00262                 }
00263         }
00264 }

Generated on Fri May 16 08:34:08 2008 for SecondLife by  doxygen 1.5.5