diff options
author | maxim_productengine <mnikolenko@productengine.com> | 2018-06-18 17:49:49 +0300 |
---|---|---|
committer | maxim_productengine <mnikolenko@productengine.com> | 2018-06-18 17:49:49 +0300 |
commit | bbc49ea0b6fba760954f0ed8cc89434ef83afcc5 (patch) | |
tree | 641c2461e00e021aed966293d41bd6eba5c65c04 | |
parent | dc580b3a0af5528329052f014a80365e3c34c353 (diff) |
MAINT-8759 FIXED [Win] Choosing new cache location will cause disconnect if you do not choose desired path in File picker quickly
-rw-r--r-- | indra/newview/llappviewer.cpp | 5 | ||||
-rw-r--r-- | indra/newview/lldirpicker.cpp | 153 | ||||
-rw-r--r-- | indra/newview/lldirpicker.h | 42 | ||||
-rw-r--r-- | indra/newview/llfloaterpreference.cpp | 39 | ||||
-rw-r--r-- | indra/newview/llfloaterpreference.h | 2 |
5 files changed, 190 insertions, 51 deletions
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index b9e2657351..acec68f393 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -42,6 +42,7 @@ #include "llagentlanguage.h" #include "llagentui.h" #include "llagentwearables.h" +#include "lldirpicker.h" #include "llfloaterimcontainer.h" #include "llimprocessing.h" #include "llwindow.h" @@ -1985,6 +1986,7 @@ bool LLAppViewer::cleanup() mAppCoreHttp.cleanup(); SUBSYSTEM_CLEANUP(LLFilePickerThread); + SUBSYSTEM_CLEANUP(LLDirPickerThread); //MUST happen AFTER SUBSYSTEM_CLEANUP(LLCurl) delete sTextureCache; @@ -2155,6 +2157,7 @@ bool LLAppViewer::initThreads() gMeshRepo.init(); LLFilePickerThread::initClass(); + LLDirPickerThread::initClass(); // *FIX: no error handling here! return true; @@ -4589,7 +4592,7 @@ void LLAppViewer::idle() LLSmoothInterpolation::updateInterpolants(); LLMortician::updateClass(); LLFilePickerThread::clearDead(); //calls LLFilePickerThread::notify() - + LLDirPickerThread::clearDead(); F32 dt_raw = idle_timer.getElapsedTimeAndResetF32(); // Cap out-of-control frame times diff --git a/indra/newview/lldirpicker.cpp b/indra/newview/lldirpicker.cpp index 5c4f0f4d5d..768b1c2021 100644 --- a/indra/newview/lldirpicker.cpp +++ b/indra/newview/lldirpicker.cpp @@ -77,6 +77,14 @@ LLDirPicker::LLDirPicker() : mFileName(NULL), mLocked(false) { + bi.hwndOwner = NULL;
+ bi.pidlRoot = NULL;
+ bi.pszDisplayName = NULL;
+ bi.lpszTitle = NULL;
+ bi.ulFlags = BIF_USENEWUI;
+ bi.lpfn = NULL;
+ bi.lParam = NULL;
+ bi.iImage = 0; } LLDirPicker::~LLDirPicker() @@ -84,7 +92,7 @@ LLDirPicker::~LLDirPicker() // nothing } -BOOL LLDirPicker::getDir(std::string* filename) +BOOL LLDirPicker::getDir(std::string filename, bool blocking) { if( mLocked ) { @@ -99,39 +107,39 @@ BOOL LLDirPicker::getDir(std::string* filename) BOOL success = FALSE; - // Modal, so pause agent - send_agent_pause(); - - BROWSEINFO bi; - memset(&bi, 0, sizeof(bi)); - - bi.ulFlags = BIF_USENEWUI; - bi.hwndOwner = (HWND)gViewerWindow->getPlatformWindow(); - bi.lpszTitle = NULL; - - ::OleInitialize(NULL); + + if (blocking) + { + // Modal, so pause agent + send_agent_pause(); + } - LPITEMIDLIST pIDL = ::SHBrowseForFolder(&bi); + bi.hwndOwner = (HWND)gViewerWindow->getPlatformWindow(); - if(pIDL != NULL) - { - WCHAR buffer[_MAX_PATH] = {'\0'}; + ::OleInitialize(NULL); + LPITEMIDLIST pIDL = ::SHBrowseForFolder(&bi); - if(::SHGetPathFromIDList(pIDL, buffer) != 0) - { - // Set the string value. + if(pIDL != NULL) + { + WCHAR buffer[_MAX_PATH] = {'\0'}; - mDir = utf16str_to_utf8str(llutf16string(buffer)); - success = TRUE; - } + if(::SHGetPathFromIDList(pIDL, buffer) != 0) + { + // Set the string value. - // free the item id list - CoTaskMemFree(pIDL); - } + mDir = utf16str_to_utf8str(llutf16string(buffer)); + success = TRUE; + } + // free the item id list + CoTaskMemFree(pIDL); + } - ::OleUninitialize(); + ::OleUninitialize(); - send_agent_resume(); + if (blocking) + { + send_agent_resume(); + } // Account for the fact that the app has been stalled. LLFrameTimer::updateFrameTime(); @@ -267,3 +275,94 @@ std::string LLDirPicker::getDirName() } #endif + + +LLMutex* LLDirPickerThread::sMutex = NULL; +std::queue<LLDirPickerThread*> LLDirPickerThread::sDeadQ; + +void LLDirPickerThread::getFile() +{ +#if LL_WINDOWS + start(); +#else + run(); +#endif +} + +//virtual +void LLDirPickerThread::run() +{ +#if LL_WINDOWS + bool blocking = false; +#else + bool blocking = true; // modal +#endif + + LLDirPicker picker; + + if (picker.getDir(mProposedName, blocking)) + { + mResponses.push_back(picker.getDirName()); + } + + { + LLMutexLock lock(sMutex); + sDeadQ.push(this); + } + +} + +//static +void LLDirPickerThread::initClass() +{ + sMutex = new LLMutex(NULL); +} + +//static +void LLDirPickerThread::cleanupClass() +{ + clearDead(); + + delete sMutex; + sMutex = NULL; +} + +//static +void LLDirPickerThread::clearDead() +{ + if (!sDeadQ.empty()) + { + LLMutexLock lock(sMutex); + while (!sDeadQ.empty()) + { + LLDirPickerThread* thread = sDeadQ.front(); + thread->notify(thread->mResponses); + delete thread; + sDeadQ.pop(); + } + } +} + +LLDirPickerThread::LLDirPickerThread(const dir_picked_signal_t::slot_type& cb, const std::string &proposed_name) + : LLThread("dir picker"), + mFilePickedSignal(NULL) +{ + mFilePickedSignal = new dir_picked_signal_t(); + mFilePickedSignal->connect(cb); +} + +LLDirPickerThread::~LLDirPickerThread() +{ + delete mFilePickedSignal; +} + +void LLDirPickerThread::notify(const std::vector<std::string>& filenames) +{ + if (!filenames.empty()) + { + if (mFilePickedSignal) + { + (*mFilePickedSignal)(filenames, mProposedName); + } + } +} diff --git a/indra/newview/lldirpicker.h b/indra/newview/lldirpicker.h index 8656b23afd..c1087c70ac 100644 --- a/indra/newview/lldirpicker.h +++ b/indra/newview/lldirpicker.h @@ -33,6 +33,13 @@ #include "stdtypes.h" +#include "llthread.h" +#include <queue> + +#if LL_WINDOWS +#include <shlobj.h> +#endif + #if LL_DARWIN // AssertMacros.h does bad things. @@ -53,7 +60,7 @@ public: // calling this before main() is undefined static LLDirPicker& instance( void ) { return sInstance; } - BOOL getDir(std::string* filename); + BOOL getDir(std::string filename, bool blocking = true); std::string getDirName(); // clear any lists of buffers or whatever, and make sure the dir @@ -76,11 +83,15 @@ private: LLFilePicker *mFilePicker; #endif + std::string* mFileName; std::string mDir; bool mLocked; static LLDirPicker sInstance; +#if LL_WINDOWS + BROWSEINFO bi; +#endif public: // don't call these directly please. @@ -88,4 +99,33 @@ public: ~LLDirPicker(); }; +class LLDirPickerThread : public LLThread +{ +public: + + static std::queue<LLDirPickerThread*> sDeadQ; + static LLMutex* sMutex; + + static void initClass(); + static void cleanupClass(); + static void clearDead(); + + std::vector<std::string> mResponses; + std::string mProposedName; + + typedef boost::signals2::signal<void(const std::vector<std::string>& filenames, std::string proposed_name)> dir_picked_signal_t; + + LLDirPickerThread(const dir_picked_signal_t::slot_type& cb, const std::string &proposed_name); + ~LLDirPickerThread(); + + void getFile(); + + virtual void run(); + + virtual void notify(const std::vector<std::string>& filenames); + +private: + dir_picked_signal_t* mFilePickedSignal; +}; + #endif diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 9d723bdd9d..4ce35643b1 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -1096,16 +1096,15 @@ void LLFloaterPreference::onClickSetCache() std::string proposed_name(cur_name); - LLDirPicker& picker = LLDirPicker::instance(); - if (! picker.getDir(&proposed_name ) ) - { - return; //Canceled! - } + (new LLDirPickerThread(boost::bind(&LLFloaterPreference::changeCachePath, this, _1, _2), proposed_name))->getFile(); +} - std::string dir_name = picker.getDirName(); - if (!dir_name.empty() && dir_name != cur_name) +void LLFloaterPreference::changeCachePath(const std::vector<std::string>& filenames, std::string proposed_name) +{ + std::string dir_name = filenames[0]; + if (!dir_name.empty() && dir_name != proposed_name) { - std::string new_top_folder(gDirUtilp->getBaseFileName(dir_name)); + std::string new_top_folder(gDirUtilp->getBaseFileName(dir_name)); LLNotificationsUtil::add("CacheWillBeMoved"); gSavedSettings.setString("NewCacheLocation", dir_name); gSavedSettings.setString("NewCacheLocationTopFolder", new_top_folder); @@ -1744,25 +1743,21 @@ void LLFloaterPreference::onClickLogPath() std::string proposed_name(gSavedPerAccountSettings.getString("InstantMessageLogPath")); mPriorInstantMessageLogPath.clear(); - LLDirPicker& picker = LLDirPicker::instance(); - //Launches a directory picker and waits for feedback - if (!picker.getDir(&proposed_name ) ) - { - return; //Canceled! - } - //Gets the path from the directory picker - std::string dir_name = picker.getDirName(); + (new LLDirPickerThread(boost::bind(&LLFloaterPreference::changeLogPath, this, _1, _2), proposed_name))->getFile(); +} +void LLFloaterPreference::changeLogPath(const std::vector<std::string>& filenames, std::string proposed_name) +{ //Path changed - if(proposed_name != dir_name) + if (proposed_name != filenames[0]) { - gSavedPerAccountSettings.setString("InstantMessageLogPath", dir_name); + gSavedPerAccountSettings.setString("InstantMessageLogPath", filenames[0]); mPriorInstantMessageLogPath = proposed_name; - - // enable/disable 'Delete transcripts button - updateDeleteTranscriptsButton(); -} + + // enable/disable 'Delete transcripts button + updateDeleteTranscriptsButton(); + } } bool LLFloaterPreference::moveTranscriptsAndLog() diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index 0cd7bac20f..8339a18296 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -133,6 +133,7 @@ public: void setCacheLocation(const LLStringExplicit& location); void onClickSetCache(); + void changeCachePath(const std::vector<std::string>& filenames, std::string proposed_name); void onClickResetCache(); void onClickSkin(LLUICtrl* ctrl,const LLSD& userdata); void onSelectSkin(); @@ -145,6 +146,7 @@ public: void resetAllIgnored(); void setAllIgnored(); void onClickLogPath(); + void changeLogPath(const std::vector<std::string>& filenames, std::string proposed_name); bool moveTranscriptsAndLog(); void enableHistory(); void setPersonalInfo(const std::string& visibility, bool im_via_email, bool is_verified_email); |