diff options
author | Jacek Antonelli | 2008-10-31 18:57:44 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-10-31 18:57:44 -0500 |
commit | 8a81ec3cc7f5998f7d75ef24f57bd9fc6eec1312 (patch) | |
tree | 606a35c18cf584a4a9e3182f69e929772a4d7bdf /linden/indra | |
parent | Disable fmod by default. (diff) | |
parent | Merge branch 'VWR-2003' into nicholaz-patches (diff) | |
download | meta-impy-8a81ec3cc7f5998f7d75ef24f57bd9fc6eec1312.zip meta-impy-8a81ec3cc7f5998f7d75ef24f57bd9fc6eec1312.tar.gz meta-impy-8a81ec3cc7f5998f7d75ef24f57bd9fc6eec1312.tar.bz2 meta-impy-8a81ec3cc7f5998f7d75ef24f57bd9fc6eec1312.tar.xz |
Merge branch 'nicholaz-patches' into next
Diffstat (limited to '')
-rw-r--r-- | linden/indra/llmessage/llassetstorage.cpp | 41 | ||||
-rw-r--r-- | linden/indra/newview/llfloateractivespeakers.cpp | 4 | ||||
-rw-r--r-- | linden/indra/newview/lltexturecache.cpp | 68 | ||||
-rw-r--r-- | linden/indra/newview/lltexturecache.h | 5 | ||||
-rw-r--r-- | linden/indra/newview/lltooldraganddrop.cpp | 6 | ||||
-rw-r--r-- | linden/indra/newview/llviewerjointattachment.h | 3 | ||||
-rw-r--r-- | linden/indra/newview/llviewerobjectlist.cpp | 4 |
7 files changed, 101 insertions, 30 deletions
diff --git a/linden/indra/llmessage/llassetstorage.cpp b/linden/indra/llmessage/llassetstorage.cpp index fa14a2b..2d85011 100644 --- a/linden/indra/llmessage/llassetstorage.cpp +++ b/linden/indra/llmessage/llassetstorage.cpp | |||
@@ -522,16 +522,19 @@ void LLAssetStorage::downloadCompleteCallback( | |||
522 | S32 result, | 522 | S32 result, |
523 | const LLUUID& file_id, | 523 | const LLUUID& file_id, |
524 | LLAssetType::EType file_type, | 524 | LLAssetType::EType file_type, |
525 | void* user_data, LLExtStat ext_status) | 525 | void* callback_parm_req, LLExtStat ext_status) |
526 | { | 526 | { |
527 | lldebugs << "LLAssetStorage::downloadCompleteCallback() for " << file_id | 527 | lldebugs << "LLAssetStorage::downloadCompleteCallback() for " << file_id |
528 | << "," << LLAssetType::lookup(file_type) << llendl; | 528 | << "," << LLAssetType::lookup(file_type) << llendl; |
529 | LLAssetRequest* req = (LLAssetRequest*)user_data; | 529 | |
530 | // be careful! req may be a ptr to memory already freed (a timeout does this) | ||
531 | LLAssetRequest* req = (LLAssetRequest*)callback_parm_req; | ||
530 | if(!req) | 532 | if(!req) |
531 | { | 533 | { |
532 | llwarns << "LLAssetStorage::downloadCompleteCallback called without" | 534 | llwarns << "LLAssetStorage::downloadCompleteCallback called without" |
533 | "a valid request." << llendl; | 535 | "a valid request." << llendl; |
534 | return; | 536 | // we can live with a null pointer, we're not allowed to deref the ptr anyway (see above) |
537 | // return; | ||
535 | } | 538 | } |
536 | if (!gAssetStorage) | 539 | if (!gAssetStorage) |
537 | { | 540 | { |
@@ -539,12 +542,10 @@ void LLAssetStorage::downloadCompleteCallback( | |||
539 | return; | 542 | return; |
540 | } | 543 | } |
541 | 544 | ||
542 | req->setUUID(file_id); | ||
543 | req->setType(file_type); | ||
544 | if (LL_ERR_NOERR == result) | 545 | if (LL_ERR_NOERR == result) |
545 | { | 546 | { |
546 | // we might have gotten a zero-size file | 547 | // we might have gotten a zero-size file |
547 | LLVFile vfile(gAssetStorage->mVFS, req->getUUID(), req->getType()); | 548 | LLVFile vfile(gAssetStorage->mVFS, file_id, file_type); |
548 | if (vfile.getSize() <= 0) | 549 | if (vfile.getSize() <= 0) |
549 | { | 550 | { |
550 | llwarns << "downloadCompleteCallback has non-existent or zero-size asset " << req->getUUID() << llendl; | 551 | llwarns << "downloadCompleteCallback has non-existent or zero-size asset " << req->getUUID() << llendl; |
@@ -563,7 +564,7 @@ void LLAssetStorage::downloadCompleteCallback( | |||
563 | { | 564 | { |
564 | request_list_t::iterator curiter = iter++; | 565 | request_list_t::iterator curiter = iter++; |
565 | LLAssetRequest* tmp = *curiter; | 566 | LLAssetRequest* tmp = *curiter; |
566 | if ((tmp->getUUID() == req->getUUID()) && (tmp->getType()== req->getType())) | 567 | if ((tmp->getUUID() == file_id) && (tmp->getType() == file_type)) |
567 | { | 568 | { |
568 | requests.push_front(tmp); | 569 | requests.push_front(tmp); |
569 | iter = gAssetStorage->mPendingDownloads.erase(curiter); | 570 | iter = gAssetStorage->mPendingDownloads.erase(curiter); |
@@ -576,7 +577,7 @@ void LLAssetStorage::downloadCompleteCallback( | |||
576 | LLAssetRequest* tmp = *curiter; | 577 | LLAssetRequest* tmp = *curiter; |
577 | if (tmp->mDownCallback) | 578 | if (tmp->mDownCallback) |
578 | { | 579 | { |
579 | tmp->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getType(), tmp->mUserData, result, ext_status); | 580 | tmp->mDownCallback(gAssetStorage->mVFS, tmp->getUUID(), tmp->getType(), tmp->mUserData, result, ext_status); |
580 | } | 581 | } |
581 | delete tmp; | 582 | delete tmp; |
582 | } | 583 | } |
@@ -672,10 +673,10 @@ void LLAssetStorage::downloadEstateAssetCompleteCallback( | |||
672 | S32 result, | 673 | S32 result, |
673 | const LLUUID& file_id, | 674 | const LLUUID& file_id, |
674 | LLAssetType::EType file_type, | 675 | LLAssetType::EType file_type, |
675 | void* user_data, | 676 | void* callback_parm_req, |
676 | LLExtStat ext_status) | 677 | LLExtStat ext_status) |
677 | { | 678 | { |
678 | LLEstateAssetRequest *req = (LLEstateAssetRequest*)user_data; | 679 | LLEstateAssetRequest *req = (LLEstateAssetRequest*)callback_parm_req; |
679 | if(!req) | 680 | if(!req) |
680 | { | 681 | { |
681 | llwarns << "LLAssetStorage::downloadEstateAssetCompleteCallback called" | 682 | llwarns << "LLAssetStorage::downloadEstateAssetCompleteCallback called" |
@@ -689,12 +690,10 @@ void LLAssetStorage::downloadEstateAssetCompleteCallback( | |||
689 | return; | 690 | return; |
690 | } | 691 | } |
691 | 692 | ||
692 | req->setUUID(file_id); | ||
693 | req->setType(file_type); | ||
694 | if (LL_ERR_NOERR == result) | 693 | if (LL_ERR_NOERR == result) |
695 | { | 694 | { |
696 | // we might have gotten a zero-size file | 695 | // we might have gotten a zero-size file |
697 | LLVFile vfile(gAssetStorage->mVFS, req->getUUID(), req->getAType()); | 696 | LLVFile vfile(gAssetStorage->mVFS, file_id, file_type); |
698 | if (vfile.getSize() <= 0) | 697 | if (vfile.getSize() <= 0) |
699 | { | 698 | { |
700 | llwarns << "downloadCompleteCallback has non-existent or zero-size asset!" << llendl; | 699 | llwarns << "downloadCompleteCallback has non-existent or zero-size asset!" << llendl; |
@@ -704,7 +703,9 @@ void LLAssetStorage::downloadEstateAssetCompleteCallback( | |||
704 | } | 703 | } |
705 | } | 704 | } |
706 | 705 | ||
707 | req->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getAType(), req->mUserData, result, ext_status); | 706 | req->mDownCallback(gAssetStorage->mVFS, file_id, file_type, req->mUserData, result, ext_status); |
707 | |||
708 | delete req; | ||
708 | } | 709 | } |
709 | 710 | ||
710 | void LLAssetStorage::getInvItemAsset(const LLHost &object_sim, const LLUUID &agent_id, const LLUUID &session_id, | 711 | void LLAssetStorage::getInvItemAsset(const LLHost &object_sim, const LLUUID &agent_id, const LLUUID &session_id, |
@@ -809,10 +810,10 @@ void LLAssetStorage::downloadInvItemCompleteCallback( | |||
809 | S32 result, | 810 | S32 result, |
810 | const LLUUID& file_id, | 811 | const LLUUID& file_id, |
811 | LLAssetType::EType file_type, | 812 | LLAssetType::EType file_type, |
812 | void* user_data, | 813 | void* callback_parm_req, |
813 | LLExtStat ext_status) | 814 | LLExtStat ext_status) |
814 | { | 815 | { |
815 | LLInvItemRequest *req = (LLInvItemRequest*)user_data; | 816 | LLInvItemRequest *req = (LLInvItemRequest*)callback_parm_req; |
816 | if(!req) | 817 | if(!req) |
817 | { | 818 | { |
818 | llwarns << "LLAssetStorage::downloadEstateAssetCompleteCallback called" | 819 | llwarns << "LLAssetStorage::downloadEstateAssetCompleteCallback called" |
@@ -825,12 +826,10 @@ void LLAssetStorage::downloadInvItemCompleteCallback( | |||
825 | return; | 826 | return; |
826 | } | 827 | } |
827 | 828 | ||
828 | req->setUUID(file_id); | ||
829 | req->setType(file_type); | ||
830 | if (LL_ERR_NOERR == result) | 829 | if (LL_ERR_NOERR == result) |
831 | { | 830 | { |
832 | // we might have gotten a zero-size file | 831 | // we might have gotten a zero-size file |
833 | LLVFile vfile(gAssetStorage->mVFS, req->getUUID(), req->getType()); | 832 | LLVFile vfile(gAssetStorage->mVFS, file_id, file_type); |
834 | if (vfile.getSize() <= 0) | 833 | if (vfile.getSize() <= 0) |
835 | { | 834 | { |
836 | llwarns << "downloadCompleteCallback has non-existent or zero-size asset!" << llendl; | 835 | llwarns << "downloadCompleteCallback has non-existent or zero-size asset!" << llendl; |
@@ -840,7 +839,9 @@ void LLAssetStorage::downloadInvItemCompleteCallback( | |||
840 | } | 839 | } |
841 | } | 840 | } |
842 | 841 | ||
843 | req->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getType(), req->mUserData, result, ext_status); | 842 | req->mDownCallback(gAssetStorage->mVFS, file_id, file_type, req->mUserData, result, ext_status); |
843 | |||
844 | delete req; | ||
844 | } | 845 | } |
845 | 846 | ||
846 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// | 847 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
diff --git a/linden/indra/newview/llfloateractivespeakers.cpp b/linden/indra/newview/llfloateractivespeakers.cpp index 2352be3..4561110 100644 --- a/linden/indra/newview/llfloateractivespeakers.cpp +++ b/linden/indra/newview/llfloateractivespeakers.cpp | |||
@@ -1363,7 +1363,7 @@ void LLLocalSpeakerMgr::updateSpeakerList() | |||
1363 | for(avatar_it = LLCharacter::sInstances.begin(); avatar_it != LLCharacter::sInstances.end(); ++avatar_it) | 1363 | for(avatar_it = LLCharacter::sInstances.begin(); avatar_it != LLCharacter::sInstances.end(); ++avatar_it) |
1364 | { | 1364 | { |
1365 | LLVOAvatar* avatarp = (LLVOAvatar*)*avatar_it; | 1365 | LLVOAvatar* avatarp = (LLVOAvatar*)*avatar_it; |
1366 | if (dist_vec(avatarp->getPositionAgent(), gAgent.getPositionAgent()) <= CHAT_NORMAL_RADIUS) | 1366 | if (!avatarp->isDead() && dist_vec(avatarp->getPositionAgent(), gAgent.getPositionAgent()) <= CHAT_NORMAL_RADIUS) |
1367 | { | 1367 | { |
1368 | setSpeaker(avatarp->getID()); | 1368 | setSpeaker(avatarp->getID()); |
1369 | } | 1369 | } |
@@ -1377,7 +1377,7 @@ void LLLocalSpeakerMgr::updateSpeakerList() | |||
1377 | if (speakerp->mStatus == LLSpeaker::STATUS_TEXT_ONLY) | 1377 | if (speakerp->mStatus == LLSpeaker::STATUS_TEXT_ONLY) |
1378 | { | 1378 | { |
1379 | LLVOAvatar* avatarp = (LLVOAvatar*)gObjectList.findObject(speaker_id); | 1379 | LLVOAvatar* avatarp = (LLVOAvatar*)gObjectList.findObject(speaker_id); |
1380 | if (!avatarp || dist_vec(avatarp->getPositionAgent(), gAgent.getPositionAgent()) > CHAT_NORMAL_RADIUS) | 1380 | if (!avatarp || avatarp->isDead() || dist_vec(avatarp->getPositionAgent(), gAgent.getPositionAgent()) > CHAT_NORMAL_RADIUS) |
1381 | { | 1381 | { |
1382 | speakerp->mStatus = LLSpeaker::STATUS_NOT_IN_CHANNEL; | 1382 | speakerp->mStatus = LLSpeaker::STATUS_NOT_IN_CHANNEL; |
1383 | speakerp->mDotColor = INACTIVE_COLOR; | 1383 | speakerp->mDotColor = INACTIVE_COLOR; |
diff --git a/linden/indra/newview/lltexturecache.cpp b/linden/indra/newview/lltexturecache.cpp index ce35377..8044859 100644 --- a/linden/indra/newview/lltexturecache.cpp +++ b/linden/indra/newview/lltexturecache.cpp | |||
@@ -892,6 +892,8 @@ LLTextureCache::LLTextureCache(bool threaded) | |||
892 | 892 | ||
893 | LLTextureCache::~LLTextureCache() | 893 | LLTextureCache::~LLTextureCache() |
894 | { | 894 | { |
895 | purgeTextureFilesTimeSliced(TRUE); // force-flush all pending file deletes | ||
896 | |||
895 | apr_pool_destroy(mFileAPRPool); | 897 | apr_pool_destroy(mFileAPRPool); |
896 | } | 898 | } |
897 | 899 | ||
@@ -1196,7 +1198,7 @@ void LLTextureCache::purgeTextures(bool validate) | |||
1196 | return; | 1198 | return; |
1197 | } | 1199 | } |
1198 | 1200 | ||
1199 | LL_DEBUGS("TextureCache") << "TEXTURE CACHE: Reading Entries..." << LL_ENDL; | 1201 | LL_DEBUGS("TextureCache") << "TEXTURE CACHE: Reading " << num_entries << " Entries from " << mTexturesDirEntriesFileName << LL_ENDL; |
1200 | 1202 | ||
1201 | std::map<LLUUID, S32> entry_idx_map; | 1203 | std::map<LLUUID, S32> entry_idx_map; |
1202 | S64 total_size = 0; | 1204 | S64 total_size = 0; |
@@ -1225,7 +1227,7 @@ void LLTextureCache::purgeTextures(bool validate) | |||
1225 | LL_DEBUGS("TextureCache") << "TEXTURE CACHE: Validating: " << validate_idx << LL_ENDL; | 1227 | LL_DEBUGS("TextureCache") << "TEXTURE CACHE: Validating: " << validate_idx << LL_ENDL; |
1226 | } | 1228 | } |
1227 | 1229 | ||
1228 | S64 min_cache_size = (sCacheMaxTexturesSize * 9) / 10; | 1230 | S64 min_cache_size = sCacheMaxTexturesSize / 100 * 95; |
1229 | S32 purge_count = 0; | 1231 | S32 purge_count = 0; |
1230 | S32 next_idx = 0; | 1232 | S32 next_idx = 0; |
1231 | for (S32 idx=0; idx<num_entries; idx++) | 1233 | for (S32 idx=0; idx<num_entries; idx++) |
@@ -1259,8 +1261,8 @@ void LLTextureCache::purgeTextures(bool validate) | |||
1259 | if (purge_entry) | 1261 | if (purge_entry) |
1260 | { | 1262 | { |
1261 | purge_count++; | 1263 | purge_count++; |
1262 | LL_DEBUGS("TextureCache") << "PURGING: " << filename << LL_ENDL; | 1264 | LL_DEBUGS("TextureCache") << "PURGING: " << filename << LL_ENDL; |
1263 | ll_apr_file_remove(filename, NULL); | 1265 | mFilesToDelete.push_back(filename); |
1264 | total_size -= entries[idx].mSize; | 1266 | total_size -= entries[idx].mSize; |
1265 | entries[idx].mSize = 0; | 1267 | entries[idx].mSize = 0; |
1266 | } | 1268 | } |
@@ -1275,7 +1277,11 @@ void LLTextureCache::purgeTextures(bool validate) | |||
1275 | } | 1277 | } |
1276 | num_entries = next_idx; | 1278 | num_entries = next_idx; |
1277 | 1279 | ||
1278 | LL_DEBUGS("TextureCache") << "TEXTURE CACHE: Writing Entries: " << num_entries << LL_ENDL; | 1280 | mTimeLastFileDelete.reset(); |
1281 | |||
1282 | LL_DEBUGS("TextureCache") << "TEXTURE CACHE: Writing Entries: " | ||
1283 | << num_entries << " (" << num_entries*sizeof(Entry)/1024 << "KB)" | ||
1284 | << LL_ENDL; | ||
1279 | 1285 | ||
1280 | ll_apr_file_remove(mTexturesDirEntriesFileName, NULL); | 1286 | ll_apr_file_remove(mTexturesDirEntriesFileName, NULL); |
1281 | ll_apr_file_write_ex(mTexturesDirEntriesFileName, NULL, | 1287 | ll_apr_file_write_ex(mTexturesDirEntriesFileName, NULL, |
@@ -1298,10 +1304,56 @@ void LLTextureCache::purgeTextures(bool validate) | |||
1298 | LL_INFOS("TextureCache") << "TEXTURE CACHE:" | 1304 | LL_INFOS("TextureCache") << "TEXTURE CACHE:" |
1299 | << " PURGED: " << purge_count | 1305 | << " PURGED: " << purge_count |
1300 | << " ENTRIES: " << num_entries | 1306 | << " ENTRIES: " << num_entries |
1301 | << " CACHE SIZE: " << total_size / 1024*1024 << " MB" | 1307 | << " CACHE SIZE: " << total_size/1024/1024 << " MB" |
1302 | << llendl; | 1308 | << llendl; |
1303 | } | 1309 | } |
1304 | 1310 | ||
1311 | |||
1312 | void LLTextureCache::purgeTextureFilesTimeSliced(BOOL force_all) | ||
1313 | { | ||
1314 | LLMutexLock lock(&mHeaderMutex); | ||
1315 | |||
1316 | F32 delay_between_passes = 1.0f; // seconds | ||
1317 | F32 max_time_per_pass = 0.1f; // seconds | ||
1318 | |||
1319 | if (!force_all && mTimeLastFileDelete.getElapsedTimeF32() <= delay_between_passes) | ||
1320 | { | ||
1321 | return; | ||
1322 | } | ||
1323 | |||
1324 | LLTimer timer; | ||
1325 | S32 howmany = 0; | ||
1326 | |||
1327 | if (mFilesToDelete.size() > 0) | ||
1328 | { | ||
1329 | llinfos << "TEXTURE CACHE: " << mFilesToDelete.size() << " files scheduled for deletion" << llendl; | ||
1330 | } | ||
1331 | |||
1332 | for (LLTextureCache::filename_list_t::iterator iter = mFilesToDelete.begin(); iter!=mFilesToDelete.end(); ) | ||
1333 | { | ||
1334 | LLTextureCache::filename_list_t::iterator iter2 = iter++; | ||
1335 | ll_apr_file_remove(*iter2, NULL); | ||
1336 | mFilesToDelete.erase(iter2); | ||
1337 | howmany++; | ||
1338 | |||
1339 | if (!force_all && timer.getElapsedTimeF32() > max_time_per_pass) | ||
1340 | { | ||
1341 | break; | ||
1342 | } | ||
1343 | } | ||
1344 | |||
1345 | if (!mFilesToDelete.empty()) | ||
1346 | { | ||
1347 | llinfos << "TEXTURE CACHE: "<< howmany << " files deleted (" | ||
1348 | << mFilesToDelete.size() << " files left for next pass)" | ||
1349 | << llendl; | ||
1350 | } | ||
1351 | |||
1352 | mTimeLastFileDelete.reset(); | ||
1353 | } | ||
1354 | |||
1355 | |||
1356 | |||
1305 | ////////////////////////////////////////////////////////////////////////////// | 1357 | ////////////////////////////////////////////////////////////////////////////// |
1306 | 1358 | ||
1307 | // call lockWorkers() first! | 1359 | // call lockWorkers() first! |
@@ -1471,6 +1523,10 @@ LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 prio | |||
1471 | purgeTextures(false); | 1523 | purgeTextures(false); |
1472 | mDoPurge = FALSE; | 1524 | mDoPurge = FALSE; |
1473 | } | 1525 | } |
1526 | |||
1527 | purgeTextureFilesTimeSliced(); // purge textures from cache in a non-hiccup-way | ||
1528 | |||
1529 | |||
1474 | if (datasize >= TEXTURE_CACHE_ENTRY_SIZE) | 1530 | if (datasize >= TEXTURE_CACHE_ENTRY_SIZE) |
1475 | { | 1531 | { |
1476 | LLMutexLock lock(&mWorkersMutex); | 1532 | LLMutexLock lock(&mWorkersMutex); |
diff --git a/linden/indra/newview/lltexturecache.h b/linden/indra/newview/lltexturecache.h index 4bac15c..b5abb67 100644 --- a/linden/indra/newview/lltexturecache.h +++ b/linden/indra/newview/lltexturecache.h | |||
@@ -122,6 +122,7 @@ private: | |||
122 | void readHeaderCache(apr_pool_t* poolp = NULL); | 122 | void readHeaderCache(apr_pool_t* poolp = NULL); |
123 | void purgeAllTextures(bool purge_directories); | 123 | void purgeAllTextures(bool purge_directories); |
124 | void purgeTextures(bool validate); | 124 | void purgeTextures(bool validate); |
125 | void purgeTextureFilesTimeSliced(BOOL force_all = FALSE); | ||
125 | S32 getHeaderCacheEntry(const LLUUID& id, bool touch, S32* imagesize = NULL); | 126 | S32 getHeaderCacheEntry(const LLUUID& id, bool touch, S32* imagesize = NULL); |
126 | bool removeHeaderCacheEntry(const LLUUID& id); | 127 | bool removeHeaderCacheEntry(const LLUUID& id); |
127 | void lockHeaders() { mHeaderMutex.lock(); } | 128 | void lockHeaders() { mHeaderMutex.lock(); } |
@@ -143,6 +144,10 @@ private: | |||
143 | 144 | ||
144 | typedef std::vector<std::pair<LLPointer<Responder>, bool> > responder_list_t; | 145 | typedef std::vector<std::pair<LLPointer<Responder>, bool> > responder_list_t; |
145 | responder_list_t mCompletedList; | 146 | responder_list_t mCompletedList; |
147 | |||
148 | typedef std::list<std::string> filename_list_t; | ||
149 | filename_list_t mFilesToDelete; | ||
150 | LLTimer mTimeLastFileDelete; | ||
146 | 151 | ||
147 | BOOL mReadOnly; | 152 | BOOL mReadOnly; |
148 | 153 | ||
diff --git a/linden/indra/newview/lltooldraganddrop.cpp b/linden/indra/newview/lltooldraganddrop.cpp index 39070b7..72ee24b 100644 --- a/linden/indra/newview/lltooldraganddrop.cpp +++ b/linden/indra/newview/lltooldraganddrop.cpp | |||
@@ -850,6 +850,12 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop, | |||
850 | { | 850 | { |
851 | LLInventoryObject* cargo = locateInventory(item, cat); | 851 | LLInventoryObject* cargo = locateInventory(item, cat); |
852 | 852 | ||
853 | if (!cargo) | ||
854 | { | ||
855 | handled = FALSE; | ||
856 | break; | ||
857 | } | ||
858 | |||
853 | EAcceptance item_acceptance = ACCEPT_NO; | 859 | EAcceptance item_acceptance = ACCEPT_NO; |
854 | handled = handled && root_view->handleDragAndDrop(x, y, mask, FALSE, | 860 | handled = handled && root_view->handleDragAndDrop(x, y, mask, FALSE, |
855 | mCargoTypes[mCurItemIndex], | 861 | mCargoTypes[mCurItemIndex], |
diff --git a/linden/indra/newview/llviewerjointattachment.h b/linden/indra/newview/llviewerjointattachment.h index 8e665aa..a69c10c 100644 --- a/linden/indra/newview/llviewerjointattachment.h +++ b/linden/indra/newview/llviewerjointattachment.h | |||
@@ -98,8 +98,7 @@ protected: | |||
98 | void calcLOD(); | 98 | void calcLOD(); |
99 | 99 | ||
100 | protected: | 100 | protected: |
101 | // Backlink only; don't make this an LLPointer. | 101 | LLPointer<LLViewerObject> mAttachedObject; |
102 | LLViewerObject* mAttachedObject; | ||
103 | BOOL mVisibleInFirst; | 102 | BOOL mVisibleInFirst; |
104 | LLVector3 mOriginalPos; | 103 | LLVector3 mOriginalPos; |
105 | S32 mGroup; | 104 | S32 mGroup; |
diff --git a/linden/indra/newview/llviewerobjectlist.cpp b/linden/indra/newview/llviewerobjectlist.cpp index 163b039..4fac9bc 100644 --- a/linden/indra/newview/llviewerobjectlist.cpp +++ b/linden/indra/newview/llviewerobjectlist.cpp | |||
@@ -861,6 +861,10 @@ void LLViewerObjectList::killObjects(LLViewerRegion *regionp) | |||
861 | if (objectp->mRegionp == regionp) | 861 | if (objectp->mRegionp == regionp) |
862 | { | 862 | { |
863 | killObject(objectp); | 863 | killObject(objectp); |
864 | |||
865 | // invalidate region pointer. region will become invalid, but | ||
866 | // refcounted objects may survive the cleanDeadObjects() call below | ||
867 | objectp->mRegionp = NULL; | ||
864 | } | 868 | } |
865 | } | 869 | } |
866 | 870 | ||