From 47a2a2982de98c88fbc6cd17bdb897e5ec408b88 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" <vir@lindenlab.com> Date: Thu, 29 Nov 2012 11:06:10 -0500 Subject: fix for possible crash on exit in self_av_string() --- indra/newview/llappearancemgr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 4e103bb75e..9f6586a69b 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -52,7 +52,7 @@ std::string self_av_string() { - return gAgentAvatarp->avString(); + return gAgentAvatarp ? gAgentAvatarp->avString() : std::string("self_av_string error, gAgentAvatarp null"); } // RAII thingy to guarantee that a variable gets reset when the Setter -- cgit v1.2.3 From 9934cd2e29c8ea11e0859cd881d286fd56fae96e Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" <vir@lindenlab.com> Date: Fri, 30 Nov 2012 17:41:07 -0500 Subject: SH-3562 WIP - detect possible hangs in item copying --- indra/newview/llappearancemgr.cpp | 137 +++++++++++++++++++++++++++++++++----- 1 file changed, 121 insertions(+), 16 deletions(-) diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 9f6586a69b..09b0c132d2 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -154,6 +154,123 @@ LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id, const std::string } } +// Shim between inventory callback and boost function +typedef boost::function<void(const LLUUID&)> inventory_func_type; + +class LLBoostFuncInventoryCallback: public LLInventoryCallback +{ +public: + + LLBoostFuncInventoryCallback(const inventory_func_type& func): + mFunc(func) + { + } + + void fire(const LLUUID& item_id) + { + mFunc(item_id); + } + +private: + inventory_func_type mFunc; +}; + +LLPointer<LLInventoryCallback> make_inventory_func_callback(const inventory_func_type& func) +{ + return new LLBoostFuncInventoryCallback(func); +} + +void report_fire(const LLUUID& item_id) +{ + llinfos << item_id << llendl; +} + +class LLInventoryCopyMgr: public LLEventTimer +{ +public: + LLInventoryCopyMgr(LLInventoryModel::item_array_t& src_items, const LLUUID& dst_cat_id, + bool append, const std::string& phase): + mDstCatID(dst_cat_id), + mAppend(append), + mTrackingPhase(phase), + LLEventTimer(5.0) + { + for (LLInventoryModel::item_array_t::const_iterator it = src_items.begin(); + it != src_items.end(); + ++it) + { + LLViewerInventoryItem* item = *it; + mSrcTimes[item->getUUID()] = LLTimer(); + requestCopy(item->getUUID()); + } + if (!mTrackingPhase.empty()) + { + selfStartPhase(mTrackingPhase); + } + } + + void requestCopy(const LLUUID& item_id) + { + LLViewerInventoryItem *item = gInventory.getItem(item_id); + if (!item) + { + llwarns << "requestCopy item not found " << item_id << llendl; + return; + } + copy_inventory_item( + gAgent.getID(), + item->getPermissions().getOwner(), + item->getUUID(), + mDstCatID, + std::string(), + make_inventory_func_callback(boost::bind(&LLInventoryCopyMgr::onCopy,this,item->getUUID(),_1)) + ); + } + + void onCopy(const LLUUID& src_id, const LLUUID& dst_id) + { + LL_DEBUGS("Avatar") << "copied, src_id " << src_id << " to dst_id " << dst_id << " after " << mSrcTimes[src_id].getElapsedTimeF32() << " seconds" << llendl; + mSrcTimes.erase(src_id); + if (mSrcTimes.empty()) + { + onCompletion(); + } + } + + void onCompletion() + { + if (!mTrackingPhase.empty()) + { + selfStopPhase(mTrackingPhase); + } + if( LLInventoryCallbackManager::is_instantiated() ) + { + LLAppearanceMgr::instance().wearInventoryCategoryOnAvatar(gInventory.getCategory(mDstCatID), mAppend); + } + } + + // virtual + // Will be deleted after returning true - only safe to do this if all callbacks have fired. + BOOL tick() + { + bool all_done = mSrcTimes.empty(); + + if (!all_done) + { + llwarns << "possible hang in copy, waiting on " << mSrcTimes.size() << " items" << llendl; + // TODO possibly add retry logic here. + + } + return all_done; + } + +private: + std::string mTrackingPhase; + std::map<LLUUID,LLTimer> mSrcTimes; + LLUUID mDstCatID; + bool mAppend; +}; + class LLWearInventoryCategoryCallback : public LLInventoryCallback { public: @@ -1979,22 +2096,10 @@ void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool ap pid, LLFolderType::FT_NONE, name); - LLPointer<LLInventoryCallback> cb = new LLWearInventoryCategoryCallback(new_cat_id, append); - it = items->begin(); - for(; it < end; ++it) - { - item = *it; - if(item) - { - copy_inventory_item( - gAgent.getID(), - item->getPermissions().getOwner(), - item->getUUID(), - new_cat_id, - std::string(), - cb); - } - } + + // Create a CopyMgr that will copy items, manage its own destruction + new LLInventoryCopyMgr(*items, new_cat_id, append, std::string("wear_inventory_category_callback")); + // BAP fixes a lag in display of created dir. gInventory.notifyObservers(); } -- cgit v1.2.3 From f0a11b1590a8d52281683275f836ac347ccc510f Mon Sep 17 00:00:00 2001 From: "prep@lindenlab.com" <prep@lindenlab.com> Date: Fri, 30 Nov 2012 16:59:15 -0600 Subject: SH-3594: Fix for crash when outfits are changed on a non server based baking region. --- indra/llvfs/llvfile.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/indra/llvfs/llvfile.cpp b/indra/llvfs/llvfile.cpp index ca749c5eaf..03d2cc25e3 100644 --- a/indra/llvfs/llvfile.cpp +++ b/indra/llvfs/llvfile.cpp @@ -32,6 +32,7 @@ #include "llthread.h" #include "llstat.h" #include "llvfs.h" +#include "llmemory.h" const S32 LLVFile::READ = 0x00000001; const S32 LLVFile::WRITE = 0x00000002; @@ -134,13 +135,13 @@ U8* LLVFile::readFile(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, S data = NULL; } else - { - data = new U8[file_size]; + { + data = (U8*) ll_aligned_malloc_16(file_size); file.read(data, file_size); /* Flawfinder: ignore */ if (file.getLastBytesRead() != (S32)file_size) { - delete[] data; + ll_aligned_free(data); data = NULL; file_size = 0; } -- cgit v1.2.3 From 6cff95f8c74e5fd647edbb4b1fb502ee4fa9f81a Mon Sep 17 00:00:00 2001 From: Logan Dethrow <log@lindenlab.com> Date: Fri, 30 Nov 2012 18:26:56 -0500 Subject: Fix for STORM-1854. Adapted the fix based on other open source consumers of fontconfig that were encountering the same error. --- indra/llwindow/llwindowsdl.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index 3bf4a48cb6..12edb055d2 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -2646,8 +2646,9 @@ std::vector<std::string> LLWindowSDL::getDynamicFallbackFontList() if (sortpat) { // Sort the list of system fonts from most-to-least-desirable. + FcResult result; fs = FcFontSort(NULL, sortpat, elide_unicode_coverage, - NULL, NULL); + NULL, result); FcPatternDestroy(sortpat); } -- cgit v1.2.3 From 3e8fdb9daa5186d8f80f53c5e6f19c0ef95c2fda Mon Sep 17 00:00:00 2001 From: Logan Dethrow <log@lindenlab.com> Date: Sat, 1 Dec 2012 00:12:32 +0000 Subject: Fixed previous commit. --- indra/llwindow/llwindowsdl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index 12edb055d2..39f8a36a6e 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -2648,7 +2648,7 @@ std::vector<std::string> LLWindowSDL::getDynamicFallbackFontList() // Sort the list of system fonts from most-to-least-desirable. FcResult result; fs = FcFontSort(NULL, sortpat, elide_unicode_coverage, - NULL, result); + NULL, &result); FcPatternDestroy(sortpat); } -- cgit v1.2.3 From 5c245e941ace3f52dfa3539c473e2c02f207d8a3 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" <vir@lindenlab.com> Date: Mon, 3 Dec 2012 14:34:00 -0500 Subject: SH-3562 WIP --- indra/newview/llappearancemgr.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 09b0c132d2..321bf7edcb 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -239,14 +239,12 @@ public: void onCompletion() { + llinfos << "done" << llendl; if (!mTrackingPhase.empty()) { selfStopPhase(mTrackingPhase); } - if( LLInventoryCallbackManager::is_instantiated() ) - { - LLAppearanceMgr::instance().wearInventoryCategoryOnAvatar(gInventory.getCategory(mDstCatID), mAppend); - } + LLAppearanceMgr::instance().wearInventoryCategoryOnAvatar(gInventory.getCategory(mDstCatID), mAppend); } // virtual @@ -2116,7 +2114,12 @@ void LLAppearanceMgr::wearInventoryCategoryOnAvatar( LLInventoryCategory* catego // Avoid unintentionally overwriting old wearables. We have to do // this up front to avoid having to deal with the case of multiple // wearables being dirty. - if(!category) return; + if (!category) return; + + if ( !LLInventoryCallbackManager::is_instantiated() ) + { + return; + } LL_INFOS("Avatar") << self_av_string() << "wearInventoryCategoryOnAvatar '" << category->getName() << "'" << LL_ENDL; -- cgit v1.2.3 From a15ec8d014307da35b792659964cd5478d1aafe7 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed <nat@lindenlab.com> Date: Tue, 4 Dec 2012 11:06:29 -0500 Subject: tag merge of DRTVWR-255 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 636671b4c9..9e61f184f3 100755 --- a/.hgtags +++ b/.hgtags @@ -368,3 +368,4 @@ f4481df42f9a4a92bf475a80f0c51d1a4bbdfd59 DRTVWR-246 39c5204b6e800983a41ccac8ad6dc993120197c6 DRTVWR-247 7c7d57d393e8ae7b61623279de06eb4a62ccae6a DRTVWR-249 f72b50ef168c159d6e79e97aa2bcafaf8577ab99 DRTVWR-230 +b418be80903520c492e1173f3afbc4021cad5d07 DRTVWR-255 -- cgit v1.2.3 From 6735d40d9a0e03007f6f7aef954022d770c0165d Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" <vir@lindenlab.com> Date: Tue, 4 Dec 2012 17:45:01 -0500 Subject: SH-3604 WIP --- indra/newview/llappearancemgr.cpp | 108 +++++++++++++++++++++++++++----------- 1 file changed, 78 insertions(+), 30 deletions(-) diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 79106318a4..8e5f4b3684 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -186,49 +186,59 @@ void report_fire(const LLUUID& item_id) llinfos << item_id << llendl; } -class LLInventoryCopyMgr: public LLEventTimer +class LLCallAfterInventoryBatchMgr: public LLEventTimer { public: - LLInventoryCopyMgr(LLInventoryModel::item_array_t& src_items, const LLUUID& dst_cat_id, - bool append, const std::string& phase): + LLCallAfterInventoryBatchMgr(const LLUUID& dst_cat_id, + const std::string& phase_name, + nullary_func_t on_completion_func, + F32 check_period = 5.0, + F32 retry_after = 30.0, + S32 max_retries = 2 + ): mDstCatID(dst_cat_id), - mAppend(append), - mTrackingPhase(phase), - LLEventTimer(5.0) + mTrackingPhase(phase_name), + mOnCompletionFunc(on_completion_func), + mRetryAfter(retry_after), + mMaxRetries(max_retries), + LLEventTimer(check_period) + { + if (!mTrackingPhase.empty()) + { + selfStartPhase(mTrackingPhase); + } + } + + void addItems(LLInventoryModel::item_array_t& src_items) { for (LLInventoryModel::item_array_t::const_iterator it = src_items.begin(); it != src_items.end(); ++it) { LLViewerInventoryItem* item = *it; - mSrcTimes[item->getUUID()] = LLTimer(); - requestCopy(item->getUUID()); - } - if (!mTrackingPhase.empty()) - { - selfStartPhase(mTrackingPhase); + llassert(item); + addItem(item); } } - void requestCopy(const LLUUID& item_id) + void addItem(LLViewerInventoryItem *item) { - LLViewerInventoryItem *item = gInventory.getItem(item_id); + const LLUUID& item_id = item->getUUID(); if (!item) { - llwarns << "requestCopy item not found " << item_id << llendl; + llwarns << "item not found for " << item_id << llendl; return; } - copy_inventory_item( - gAgent.getID(), - item->getPermissions().getOwner(), - item->getUUID(), - mDstCatID, - std::string(), - make_inventory_func_callback(boost::bind(&LLInventoryCopyMgr::onCopy,this,item->getUUID(),_1)) - ); + if (mSrcTimes.find(item_id) == mSrcTimes.end()) + { + mSrcTimes[item->getUUID()] = LLTimer(); + } + requestOperation(item); } - - void onCopy(const LLUUID& src_id, const LLUUID& dst_id) + + virtual void requestOperation(LLViewerInventoryItem *item) = 0; + + void onOp(const LLUUID& src_id, const LLUUID& dst_id) { LL_DEBUGS("Avatar") << "copied, src_id " << src_id << " to dst_id " << dst_id << " after " << mSrcTimes[src_id].getElapsedTimeF32() << " seconds" << llendl; mSrcTimes.erase(src_id); @@ -245,7 +255,7 @@ public: { selfStopPhase(mTrackingPhase); } - LLAppearanceMgr::instance().wearInventoryCategoryOnAvatar(gInventory.getCategory(mDstCatID), mAppend); + mOnCompletionFunc(); } // virtual @@ -256,18 +266,51 @@ public: if (!all_done) { - llwarns << "possible hang in copy, waiting on " << mSrcTimes.size() << " items" << llendl; + llwarns << "possible hang in operation, waiting on " << mSrcTimes.size() << " items" << llendl; // TODO possibly add retry logic here. } return all_done; } -private: + virtual ~LLCallAfterInventoryBatchMgr() + { + LL_DEBUGS("Avatar") << "ending" << llendl; + } + +protected: std::string mTrackingPhase; std::map<LLUUID,LLTimer> mSrcTimes; LLUUID mDstCatID; - bool mAppend; + nullary_func_t mOnCompletionFunc; + F32 mRetryAfter; + S32 mMaxRetries; +}; + +class LLCallAfterInventoryCopyMgr: public LLCallAfterInventoryBatchMgr +{ +public: + LLCallAfterInventoryCopyMgr(LLInventoryModel::item_array_t& src_items, + const LLUUID& dst_cat_id, + const std::string& phase_name, + nullary_func_t on_completion_func + ): + LLCallAfterInventoryBatchMgr(dst_cat_id, phase_name, on_completion_func) + { + addItems(src_items); + } + + virtual void requestOperation(LLViewerInventoryItem *item) + { + copy_inventory_item( + gAgent.getID(), + item->getPermissions().getOwner(), + item->getUUID(), + mDstCatID, + std::string(), + make_inventory_func_callback(boost::bind(&LLCallAfterInventoryBatchMgr::onOp,this,item->getUUID(),_1)) + ); + } }; class LLWearInventoryCategoryCallback : public LLInventoryCallback @@ -2097,7 +2140,12 @@ void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool ap name); // Create a CopyMgr that will copy items, manage its own destruction - new LLInventoryCopyMgr(*items, new_cat_id, append, std::string("wear_inventory_category_callback")); + new LLCallAfterInventoryCopyMgr( + *items, new_cat_id, std::string("wear_inventory_category_callback"), + boost::bind(&LLAppearanceMgr::wearInventoryCategoryOnAvatar, + LLAppearanceMgr::getInstance(), + gInventory.getCategory(new_cat_id), + append)); // BAP fixes a lag in display of created dir. gInventory.notifyObservers(); -- cgit v1.2.3 From 32f5015ecd29ec664a79c2ce86fa7c462f5f7561 Mon Sep 17 00:00:00 2001 From: prep <prep@lindenlab.com> Date: Wed, 5 Dec 2012 14:33:30 -0500 Subject: Added back in mesa package for linux builds --- autobuild.xml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/autobuild.xml b/autobuild.xml index f5ea967b32..82344ebc90 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -1452,6 +1452,30 @@ <string>windows</string> </map> </map> + </map> + <key>mesa</key> + <map> + <key>license</key> + <string>mesa</string> + <key>license_file</key> + <string>LICENSES/mesa.txt</string> + <key>name</key> + <string>mesa</string> + <key>platforms</key> + <map> + <key>linux</key> + <map> + <key>archive</key> + <map> + <key>hash</key> + <string>1f600840463c7327ea17486821425750</string> + <key>url</key> + <string>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/mesa-7.0-linux-20100930.tar.bz2</string> + </map> + <key>name</key> + <string>linux</string> + </map> + </map> </map> <key>ndofdev</key> <map> -- cgit v1.2.3 From 480569677cb0cd6b03d2a38a613561d6ef6be059 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" <vir@lindenlab.com> Date: Wed, 5 Dec 2012 16:38:21 -0500 Subject: SH-3604 WIP - retry mechanism for batch inventory ops, handle either completion or failure --- indra/newview/app_settings/logcontrol.xml | 2 +- indra/newview/app_settings/settings.xml | 11 ++ indra/newview/llappearancemgr.cpp | 196 ++++++++++++++++++++---------- 3 files changed, 147 insertions(+), 62 deletions(-) diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml index 64122bbb6c..1259039010 100755 --- a/indra/newview/app_settings/logcontrol.xml +++ b/indra/newview/app_settings/logcontrol.xml @@ -42,8 +42,8 @@ </array> <key>tags</key> <array> - <!-- sample entry for debugging specific items <string>Avatar</string> + <!-- sample entry for debugging specific items <string>Voice</string> --> </array> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index efb1ccc1cc..4a69e5b356 100755 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -4315,6 +4315,17 @@ <key>Value</key> <real>1.0</real> </map> + <key>InventoryDebugSimulateOpFailureRate</key> + <map> + <key>Comment</key> + <string>Rate at which we simulate failures of copy/link requests in some operations</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>0.0</real> + </map> <key>InventoryDisplayInbox</key> <map> <key>Comment</key> diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 8e5f4b3684..c149f38fcd 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -192,15 +192,20 @@ public: LLCallAfterInventoryBatchMgr(const LLUUID& dst_cat_id, const std::string& phase_name, nullary_func_t on_completion_func, + nullary_func_t on_failure_func, F32 check_period = 5.0, - F32 retry_after = 30.0, + F32 retry_after = 10.0, S32 max_retries = 2 ): mDstCatID(dst_cat_id), mTrackingPhase(phase_name), mOnCompletionFunc(on_completion_func), + mOnFailureFunc(on_failure_func), mRetryAfter(retry_after), mMaxRetries(max_retries), + mPendingRequests(0), + mFailCount(0), + mRetryCount(0), LLEventTimer(check_period) { if (!mTrackingPhase.empty()) @@ -221,6 +226,7 @@ public: } } + // Request or re-request operation for specified item. void addItem(LLViewerInventoryItem *item) { const LLUUID& item_id = item->getUUID(); @@ -229,10 +235,24 @@ public: llwarns << "item not found for " << item_id << llendl; return; } - if (mSrcTimes.find(item_id) == mSrcTimes.end()) + mPendingRequests++; + // On a re-request, this will reset the timer. + mWaitTimes[item_id] = LLTimer(); + if (mRetryCounts.find(item_id) == mRetryCounts.end()) { - mSrcTimes[item->getUUID()] = LLTimer(); + mRetryCounts[item_id] = 0; } + else + { + mRetryCounts[item_id]++; + } + + if (ll_frand()<gSavedSettings.getF32("InventoryDebugSimulateOpFailureRate")) + { + // simulate server failure by not sending the request. + return; + } + requestOperation(item); } @@ -240,21 +260,46 @@ public: void onOp(const LLUUID& src_id, const LLUUID& dst_id) { - LL_DEBUGS("Avatar") << "copied, src_id " << src_id << " to dst_id " << dst_id << " after " << mSrcTimes[src_id].getElapsedTimeF32() << " seconds" << llendl; - mSrcTimes.erase(src_id); - if (mSrcTimes.empty()) + LL_DEBUGS("Avatar") << "copied, src_id " << src_id << " to dst_id " << dst_id << " after " << mWaitTimes[src_id].getElapsedTimeF32() << " seconds" << llendl; + mPendingRequests--; + F32 wait_time = mWaitTimes[src_id].getElapsedTimeF32(); + mTimeStats.push(wait_time); + mWaitTimes.erase(src_id); + if (mWaitTimes.empty()) { - onCompletion(); + onCompletionOrFailure(); } } - void onCompletion() + void onCompletionOrFailure() { - llinfos << "done" << llendl; + // Will never call onCompletion() if any item has been flagged as + // a failure - otherwise could wind up with corrupted + // outfit, involuntary nudity, etc. + reportStats(); if (!mTrackingPhase.empty()) { selfStopPhase(mTrackingPhase); } + if (!mFailCount) + { + onCompletion(); + } + else + { + onFailure(); + } + } + + void onFailure() + { + llinfos << "failed" << llendl; + mOnFailureFunc(); + } + + void onCompletion() + { + llinfos << "done" << llendl; mOnCompletionFunc(); } @@ -262,29 +307,79 @@ public: // Will be deleted after returning true - only safe to do this if all callbacks have fired. BOOL tick() { - bool all_done = mSrcTimes.empty(); + // mPendingRequests will be zero if all requests have been + // responded to. mWaitTimes.empty() will be true if we have + // received at least one reply for each UUID. If requests + // have been dropped and retried, these will not necessarily + // be the same. Only safe to return true if all requests have + // been serviced, since it will result in this object being + // deleted. + bool all_done = (mPendingRequests==0); - if (!all_done) + if (!mWaitTimes.empty()) { - llwarns << "possible hang in operation, waiting on " << mSrcTimes.size() << " items" << llendl; - // TODO possibly add retry logic here. + llwarns << "still waiting on " << mWaitTimes.size() << " items" << llendl; + for (std::map<LLUUID,LLTimer>::const_iterator it = mWaitTimes.begin(); + it != mWaitTimes.end();) + { + // Use a copy of iterator because it may be erased/invalidated. + std::map<LLUUID,LLTimer>::const_iterator curr_it = it; + ++it; + + F32 time_waited = curr_it->second.getElapsedTimeF32(); + S32 retries = mRetryCounts[curr_it->first]; + if (time_waited > mRetryAfter) + { + if (retries < mMaxRetries) + { + LL_DEBUGS("Avatar") << "Waited " << time_waited << + " for " << curr_it->first << ", retrying" << llendl; + mRetryCount++; + addItem(gInventory.getItem(curr_it->first)); + } + else + { + llwarns << "Giving up on " << curr_it->first << " after too many retries" << llendl; + mWaitTimes.erase(curr_it); + mFailCount++; + } + } + if (mWaitTimes.empty()) + { + onCompletionOrFailure(); + } + } } return all_done; } + void reportStats() + { + LL_DEBUGS("Avatar") << "mFailCount: " << mFailCount << llendl; + LL_DEBUGS("Avatar") << "mRetryCount: " << mRetryCount << llendl; + LL_DEBUGS("Avatar") << "Times: n " << mTimeStats.getCount() << " min " << mTimeStats.getMinValue() << " max " << mTimeStats.getMaxValue() << llendl; + LL_DEBUGS("Avatar") << "Mean " << mTimeStats.getMean() << " stddev " << mTimeStats.getStdDev() << llendl; + } + virtual ~LLCallAfterInventoryBatchMgr() { - LL_DEBUGS("Avatar") << "ending" << llendl; + LL_DEBUGS("Avatar") << "deleting" << llendl; } protected: std::string mTrackingPhase; - std::map<LLUUID,LLTimer> mSrcTimes; + std::map<LLUUID,LLTimer> mWaitTimes; + std::map<LLUUID,S32> mRetryCounts; LLUUID mDstCatID; nullary_func_t mOnCompletionFunc; + nullary_func_t mOnFailureFunc; F32 mRetryAfter; S32 mMaxRetries; + S32 mPendingRequests; + S32 mFailCount; + S32 mRetryCount; + LLViewerStats::StatsAccumulator mTimeStats; }; class LLCallAfterInventoryCopyMgr: public LLCallAfterInventoryBatchMgr @@ -293,9 +388,10 @@ public: LLCallAfterInventoryCopyMgr(LLInventoryModel::item_array_t& src_items, const LLUUID& dst_cat_id, const std::string& phase_name, - nullary_func_t on_completion_func + nullary_func_t on_completion_func, + nullary_func_t on_failure_func ): - LLCallAfterInventoryBatchMgr(dst_cat_id, phase_name, on_completion_func) + LLCallAfterInventoryBatchMgr(dst_cat_id, phase_name, on_completion_func, on_failure_func) { addItems(src_items); } @@ -313,56 +409,32 @@ public: } }; -class LLWearInventoryCategoryCallback : public LLInventoryCallback +class LLCallAfterInventoryLinkMgr: public LLCallAfterInventoryBatchMgr { -public: - LLWearInventoryCategoryCallback(const LLUUID& cat_id, bool append) - { - mCatID = cat_id; - mAppend = append; - - LL_INFOS("Avatar") << self_av_string() << "starting" << LL_ENDL; - - selfStartPhase("wear_inventory_category_callback"); - } - void fire(const LLUUID& item_id) + LLCallAfterInventoryLinkMgr(LLInventoryModel::item_array_t& src_items, + const LLUUID& dst_cat_id, + const std::string& phase_name, + nullary_func_t on_completion_func, + nullary_func_t on_failure_func + ): + LLCallAfterInventoryBatchMgr(dst_cat_id, phase_name, on_completion_func, on_failure_func) { - /* - * Do nothing. We only care about the destructor - * - * The reason for this is that this callback is used in a hack where the - * same callback is given to dozens of items, and the destructor is called - * after the last item has fired the event and dereferenced it -- if all - * the events actually fire! - */ - LL_DEBUGS("Avatar") << self_av_string() << " fired on copied item, id " << item_id << LL_ENDL; + addItems(src_items); } - -protected: - ~LLWearInventoryCategoryCallback() + + virtual void requestOperation(LLViewerInventoryItem *item) { - LL_INFOS("Avatar") << self_av_string() << "done all inventory callbacks" << LL_ENDL; - - selfStopPhase("wear_inventory_category_callback"); - - // Is the destructor called by ordinary dereference, or because the app's shutting down? - // If the inventory callback manager goes away, we're shutting down, no longer want the callback. - if( LLInventoryCallbackManager::is_instantiated() ) - { - LLAppearanceMgr::instance().wearInventoryCategoryOnAvatar(gInventory.getCategory(mCatID), mAppend); - } - else - { - llwarns << self_av_string() << "Dropping unhandled LLWearInventoryCategoryCallback" << llendl; - } + link_inventory_item(gAgent.getID(), + item->getLinkedUUID(), + mDstCatID, + item->getName(), + item->LLInventoryItem::getDescription(), + LLAssetType::AT_LINK, + make_inventory_func_callback( + boost::bind(&LLCallAfterInventoryBatchMgr::onOp,this,item->getUUID(),_1))); } - -private: - LLUUID mCatID; - bool mAppend; }; - //Inventory callback updating "dirty" state when destroyed class LLUpdateDirtyState: public LLInventoryCallback { @@ -2145,7 +2217,8 @@ void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool ap boost::bind(&LLAppearanceMgr::wearInventoryCategoryOnAvatar, LLAppearanceMgr::getInstance(), gInventory.getCategory(new_cat_id), - append)); + append), + boost::function<void()>()); // BAP fixes a lag in display of created dir. gInventory.notifyObservers(); @@ -2167,6 +2240,7 @@ void LLAppearanceMgr::wearInventoryCategoryOnAvatar( LLInventoryCategory* catego if ( !LLInventoryCallbackManager::is_instantiated() ) { + // shutting down, ignore. return; } -- cgit v1.2.3 From 7d419d59009d429c8d9480adf3ae163d5c688126 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" <vir@lindenlab.com> Date: Wed, 5 Dec 2012 16:39:23 -0500 Subject: SH-3604 WIP - backed out logcontrol.xml change --- indra/newview/app_settings/logcontrol.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml index 1259039010..64122bbb6c 100755 --- a/indra/newview/app_settings/logcontrol.xml +++ b/indra/newview/app_settings/logcontrol.xml @@ -42,8 +42,8 @@ </array> <key>tags</key> <array> - <string>Avatar</string> <!-- sample entry for debugging specific items + <string>Avatar</string> <string>Voice</string> --> </array> -- cgit v1.2.3 From 1004eff4a29371719f98eae378f6ecd7dc6be225 Mon Sep 17 00:00:00 2001 From: Logan Dethrow <log@lindenlab.com> Date: Wed, 5 Dec 2012 17:29:52 -0500 Subject: Linux Viewer build fixes. * Removed no longer used unpack_bufsize from bitpack_test.cpp * Added llviewertexture_stub.cpp to the newview tests directory to fix llworldmap_test.cpp and llworldmipmap_test.cpp linker errors. --- indra/llcommon/tests/bitpack_test.cpp | 1 - indra/newview/CMakeLists.txt | 9 ++++++++ indra/newview/tests/llviewertexture_stub.cpp | 32 ++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 indra/newview/tests/llviewertexture_stub.cpp diff --git a/indra/llcommon/tests/bitpack_test.cpp b/indra/llcommon/tests/bitpack_test.cpp index 49cae16400..afc0c18cd0 100644 --- a/indra/llcommon/tests/bitpack_test.cpp +++ b/indra/llcommon/tests/bitpack_test.cpp @@ -94,7 +94,6 @@ namespace tut ensure("bitPack: individual unpack: 5", unpackbuffer[0] == (U8) str[5]); bitunpack.bitUnpack(unpackbuffer, 8*4); // Life ensure_memory_matches("bitPack: 4 bytes unpack:", unpackbuffer, 4, str+6, 4); - ensure("keep compiler quiet", unpack_bufsize == unpack_bufsize); } // U32 packing diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index f85060a140..e64697982f 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -2060,6 +2060,15 @@ if (LL_TESTS) llworldmipmap.cpp ) + set_source_files_properties( + llworldmap.cpp + llworldmipmap.cpp + PROPERTIES + LL_TEST_ADDITIONAL_SOURCE_FILES + tests/llviewertexture_stub.cpp + #llviewertexturelist.cpp + ) + set_source_files_properties( lltranslate.cpp PROPERTIES diff --git a/indra/newview/tests/llviewertexture_stub.cpp b/indra/newview/tests/llviewertexture_stub.cpp new file mode 100644 index 0000000000..90e76a8f83 --- /dev/null +++ b/indra/newview/tests/llviewertexture_stub.cpp @@ -0,0 +1,32 @@ +/** + * @file llviewertexture_stub.cpp + * @brief stub class to allow unit testing + * + * $LicenseInfo:firstyear=2012&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" +#include "../llviewertexture.h" + +void LLViewerTexture::setBoostLevel(int level) +{ +} -- cgit v1.2.3 From bfa3bc0059eef269ac7a77cd28443898cea1fb19 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" <vir@lindenlab.com> Date: Wed, 5 Dec 2012 17:58:35 -0500 Subject: Possible fix for TC build failure --- indra/newview/app_settings/logcontrol.xml | 2 +- indra/newview/llappearancemgr.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml index 64122bbb6c..1259039010 100755 --- a/indra/newview/app_settings/logcontrol.xml +++ b/indra/newview/app_settings/logcontrol.xml @@ -42,8 +42,8 @@ </array> <key>tags</key> <array> - <!-- sample entry for debugging specific items <string>Avatar</string> + <!-- sample entry for debugging specific items <string>Voice</string> --> </array> diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index c149f38fcd..656949a9bb 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -319,11 +319,11 @@ public: if (!mWaitTimes.empty()) { llwarns << "still waiting on " << mWaitTimes.size() << " items" << llendl; - for (std::map<LLUUID,LLTimer>::const_iterator it = mWaitTimes.begin(); + for (std::map<LLUUID,LLTimer>::iterator it = mWaitTimes.begin(); it != mWaitTimes.end();) { // Use a copy of iterator because it may be erased/invalidated. - std::map<LLUUID,LLTimer>::const_iterator curr_it = it; + std::map<LLUUID,LLTimer>::iterator curr_it = it; ++it; F32 time_waited = curr_it->second.getElapsedTimeF32(); -- cgit v1.2.3 From 2af1f6dbdfdef0a7b7b7c4f40ac33c8d93869b1f Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" <vir@lindenlab.com> Date: Wed, 5 Dec 2012 18:04:33 -0500 Subject: removed yet another unintended commit of logcontrol.xml --- indra/newview/app_settings/logcontrol.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml index 1259039010..64122bbb6c 100755 --- a/indra/newview/app_settings/logcontrol.xml +++ b/indra/newview/app_settings/logcontrol.xml @@ -42,8 +42,8 @@ </array> <key>tags</key> <array> - <string>Avatar</string> <!-- sample entry for debugging specific items + <string>Avatar</string> <string>Voice</string> --> </array> -- cgit v1.2.3 From 1d5b98929b176f3eeda7274bf8f21b69d551a2cd Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" <vir@lindenlab.com> Date: Thu, 6 Dec 2012 15:17:00 -0500 Subject: SH-3604 FIX - switched link creation in updateCOF() to use retry path, better stats reporting, fixed failure logic --- indra/newview/llappearancemgr.cpp | 48 ++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 656949a9bb..98a8097a1e 100755 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -186,13 +186,15 @@ void report_fire(const LLUUID& item_id) llinfos << item_id << llendl; } +void no_op() {} + class LLCallAfterInventoryBatchMgr: public LLEventTimer { public: LLCallAfterInventoryBatchMgr(const LLUUID& dst_cat_id, const std::string& phase_name, nullary_func_t on_completion_func, - nullary_func_t on_failure_func, + nullary_func_t on_failure_func = no_op, F32 check_period = 5.0, F32 retry_after = 10.0, S32 max_retries = 2 @@ -205,6 +207,7 @@ public: mMaxRetries(max_retries), mPendingRequests(0), mFailCount(0), + mCompletionOrFailureCalled(false), mRetryCount(0), LLEventTimer(check_period) { @@ -260,12 +263,16 @@ public: void onOp(const LLUUID& src_id, const LLUUID& dst_id) { - LL_DEBUGS("Avatar") << "copied, src_id " << src_id << " to dst_id " << dst_id << " after " << mWaitTimes[src_id].getElapsedTimeF32() << " seconds" << llendl; + LL_DEBUGS("Avatar") << "op done, src_id " << src_id << " dst_id " << dst_id << " after " << mWaitTimes[src_id].getElapsedTimeF32() << " seconds" << llendl; mPendingRequests--; F32 wait_time = mWaitTimes[src_id].getElapsedTimeF32(); mTimeStats.push(wait_time); mWaitTimes.erase(src_id); - if (mWaitTimes.empty()) + if (mCompletionOrFailureCalled) + { + llinfos << "late-completing operation, src_id " << src_id << "dst_id " << dst_id << llendl; + } + if (mWaitTimes.empty() && !mCompletionOrFailureCalled) { onCompletionOrFailure(); } @@ -273,6 +280,9 @@ public: void onCompletionOrFailure() { + assert (!mCompletionOrFailureCalled); + mCompletionOrFailureCalled = true; + // Will never call onCompletion() if any item has been flagged as // a failure - otherwise could wind up with corrupted // outfit, involuntary nudity, etc. @@ -356,6 +366,7 @@ public: void reportStats() { + LL_DEBUGS("Avatar") << "Phase: " << mTrackingPhase << llendl; LL_DEBUGS("Avatar") << "mFailCount: " << mFailCount << llendl; LL_DEBUGS("Avatar") << "mRetryCount: " << mRetryCount << llendl; LL_DEBUGS("Avatar") << "Times: n " << mTimeStats.getCount() << " min " << mTimeStats.getMinValue() << " max " << mTimeStats.getMaxValue() << llendl; @@ -379,6 +390,7 @@ protected: S32 mPendingRequests; S32 mFailCount; S32 mRetryCount; + bool mCompletionOrFailureCalled; LLViewerStats::StatsAccumulator mTimeStats; }; @@ -389,7 +401,7 @@ public: const LLUUID& dst_cat_id, const std::string& phase_name, nullary_func_t on_completion_func, - nullary_func_t on_failure_func + nullary_func_t on_failure_func = no_op ): LLCallAfterInventoryBatchMgr(dst_cat_id, phase_name, on_completion_func, on_failure_func) { @@ -411,11 +423,12 @@ public: class LLCallAfterInventoryLinkMgr: public LLCallAfterInventoryBatchMgr { +public: LLCallAfterInventoryLinkMgr(LLInventoryModel::item_array_t& src_items, const LLUUID& dst_cat_id, const std::string& phase_name, nullary_func_t on_completion_func, - nullary_func_t on_failure_func + nullary_func_t on_failure_func = no_op ): LLCallAfterInventoryBatchMgr(dst_cat_id, phase_name, on_completion_func, on_failure_func) { @@ -1757,34 +1770,38 @@ void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append) purgeCategory(cof, keep_outfit_links); gInventory.notifyObservers(); - // Create links to new COF contents. - LL_DEBUGS("Avatar") << self_av_string() << "creating LLUpdateAppearanceOnDestroy" << LL_ENDL; - LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy(!append); - #ifndef LL_RELEASE_FOR_DOWNLOAD LL_DEBUGS("Avatar") << self_av_string() << "Linking body items" << LL_ENDL; #endif - linkAll(cof, body_items, link_waiter); + + // Create links to new COF contents. + LL_DEBUGS("Avatar") << self_av_string() << "creating LLCallAfterInventoryLinkMgr" << LL_ENDL; + bool update_base_outfit_ordering = !append; + LLCallAfterInventoryLinkMgr *link_waiter = + new LLCallAfterInventoryLinkMgr(body_items,cof,"update_appearance_on_destroy", + boost::bind(&LLAppearanceMgr::updateAppearanceFromCOF, + LLAppearanceMgr::getInstance(), + update_base_outfit_ordering)); #ifndef LL_RELEASE_FOR_DOWNLOAD LL_DEBUGS("Avatar") << self_av_string() << "Linking wear items" << LL_ENDL; #endif - linkAll(cof, wear_items, link_waiter); + link_waiter->addItems(wear_items); #ifndef LL_RELEASE_FOR_DOWNLOAD LL_DEBUGS("Avatar") << self_av_string() << "Linking obj items" << LL_ENDL; #endif - linkAll(cof, obj_items, link_waiter); + link_waiter->addItems(obj_items); #ifndef LL_RELEASE_FOR_DOWNLOAD LL_DEBUGS("Avatar") << self_av_string() << "Linking gesture items" << LL_ENDL; #endif - linkAll(cof, gest_items, link_waiter); + link_waiter->addItems(gest_items); // Add link to outfit if category is an outfit. if (!append) { - createBaseOutfitLink(category, link_waiter); + createBaseOutfitLink(category, NULL); } LL_DEBUGS("Avatar") << self_av_string() << "waiting for LLUpdateAppearanceOnDestroy" << LL_ENDL; } @@ -2217,8 +2234,7 @@ void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool ap boost::bind(&LLAppearanceMgr::wearInventoryCategoryOnAvatar, LLAppearanceMgr::getInstance(), gInventory.getCategory(new_cat_id), - append), - boost::function<void()>()); + append)); // BAP fixes a lag in display of created dir. gInventory.notifyObservers(); -- cgit v1.2.3 From 97adf6422ac61148a3334d67b4c59a5f5437af2c Mon Sep 17 00:00:00 2001 From: Logan Dethrow <log@lindenlab.com> Date: Thu, 6 Dec 2012 21:59:54 +0000 Subject: On Linux now use the default system python instead of defaulting to python2.5. This was a holdover from when on linden systems 2.5 was newer than the default, instead of older. --- indra/cmake/Python.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/cmake/Python.cmake b/indra/cmake/Python.cmake index 748c8c2bec..a81c9307fc 100644 --- a/indra/cmake/Python.cmake +++ b/indra/cmake/Python.cmake @@ -23,7 +23,7 @@ if (WINDOWS) elseif (EXISTS /etc/debian_version) # On Debian and Ubuntu, avoid Python 2.4 if possible. - find_program(PYTHON_EXECUTABLE python2.5 python2.3 python PATHS /usr/bin) + find_program(PYTHON_EXECUTABLE python PATHS /usr/bin) if (PYTHON_EXECUTABLE) set(PYTHONINTERP_FOUND ON) -- cgit v1.2.3