Merge branch 'DRTVWR-573-maint-R' of https://github.com/secondlife/viewer
# Conflicts: # indra/llfilesystem/lldiskcache.cppmeow-7.2.2
commit
f7f941ae5b
|
|
@ -35,7 +35,6 @@
|
|||
#include "llassettype.h"
|
||||
#include "lldir.h"
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <chrono>
|
||||
|
||||
#include "lldiskcache.h"
|
||||
|
|
@ -116,21 +115,20 @@ void LLDiskCache::purge()
|
|||
#endif
|
||||
if (boost::filesystem::is_directory(cache_path, ec) && !ec.failed())
|
||||
{
|
||||
// <FS:Ansariel> Optimize asset simple disk cache
|
||||
//for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(cache_path, ec), {}))
|
||||
for (auto& entry : boost::make_iterator_range(boost::filesystem::recursive_directory_iterator(cache_path, ec), {}))
|
||||
boost::filesystem::directory_iterator iter(cache_path, ec);
|
||||
while (iter != boost::filesystem::directory_iterator() && !ec.failed())
|
||||
{
|
||||
if (!ec.failed() && (boost::filesystem::is_regular_file(entry, ec) && !ec.failed()))
|
||||
if (boost::filesystem::is_regular_file(*iter, ec) && !ec.failed())
|
||||
{
|
||||
if (entry.path().string().find(mCacheFilenamePrefix) != std::string::npos)
|
||||
if ((*iter).path().string().find(mCacheFilenamePrefix) != std::string::npos)
|
||||
{
|
||||
uintmax_t file_size = boost::filesystem::file_size(entry, ec);
|
||||
uintmax_t file_size = boost::filesystem::file_size(*iter, ec);
|
||||
if (ec.failed())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const std::string file_path = entry.path().string();
|
||||
const std::time_t file_time = boost::filesystem::last_write_time(entry, ec);
|
||||
const std::string file_path = (*iter).path().string();
|
||||
const std::time_t file_time = boost::filesystem::last_write_time(*iter, ec);
|
||||
if (ec.failed())
|
||||
{
|
||||
continue;
|
||||
|
|
@ -139,6 +137,7 @@ void LLDiskCache::purge()
|
|||
file_info.push_back(file_info_t(file_time, { file_size, file_path }));
|
||||
}
|
||||
}
|
||||
iter.increment(ec);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -470,41 +469,21 @@ void LLDiskCache::clearCache()
|
|||
#endif
|
||||
if (boost::filesystem::is_directory(cache_path, ec) && !ec.failed())
|
||||
{
|
||||
LL_INFOS() << "is a directory: " << mCacheDir << LL_ENDL;
|
||||
// <FS:Ansariel> Optimize asset simple disk cache
|
||||
//for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(cache_path, ec), {}))
|
||||
// <FS:TS> FIRE-31070: Crash on clearing cache on macOS and Linux
|
||||
// On Unix-like operating systems, the recursive_directory_iterator gets very unhappy if you
|
||||
// delete a file out from under it in a for loop. This restructuring to a while loop and
|
||||
// manually incrementing the iterator avoids the problem. Note that the iterator must be
|
||||
// incremented *before* deleting the file.
|
||||
boost::filesystem::recursive_directory_iterator entry(cache_path, ec);
|
||||
boost::filesystem::recursive_directory_iterator cache_end;
|
||||
while (entry != cache_end)
|
||||
boost::filesystem::directory_iterator iter(cache_path, ec);
|
||||
while (iter != boost::filesystem::directory_iterator() && !ec.failed())
|
||||
{
|
||||
const boost::filesystem::path& remove_entry = entry->path();
|
||||
if (boost::filesystem::is_regular_file(remove_entry, ec) && !ec.failed())
|
||||
if (boost::filesystem::is_regular_file(*iter, ec) && !ec.failed())
|
||||
{
|
||||
if (remove_entry.string().find(mCacheFilenamePrefix) != std::string::npos)
|
||||
if ((*iter).path().string().find(mCacheFilenamePrefix) != std::string::npos)
|
||||
{
|
||||
const boost::filesystem::path remove_path = remove_entry;
|
||||
++entry;
|
||||
boost::filesystem::remove(remove_path, ec);
|
||||
boost::filesystem::remove(*iter, ec);
|
||||
if (ec.failed())
|
||||
{
|
||||
LL_WARNS() << "Failed to delete cache file " << remove_path.string() << ": " << ec.message() << LL_ENDL;
|
||||
LL_WARNS() << "Failed to delete cache file " << *iter << ": " << ec.message() << LL_ENDL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++entry;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
++entry;
|
||||
}
|
||||
// </FS:TS> FIRE-31070
|
||||
iter.increment(ec);
|
||||
}
|
||||
// <FS:Beq> add static assets into the new cache after clear
|
||||
LL_INFOS() << "prepopulating new cache " << LL_ENDL;
|
||||
|
|
@ -527,20 +506,22 @@ void LLDiskCache::removeOldVFSFiles()
|
|||
#endif
|
||||
if (boost::filesystem::is_directory(cache_path, ec) && !ec.failed())
|
||||
{
|
||||
for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(cache_path, ec), {}))
|
||||
boost::filesystem::directory_iterator iter(cache_path, ec);
|
||||
while (iter != boost::filesystem::directory_iterator() && !ec.failed())
|
||||
{
|
||||
if (boost::filesystem::is_regular_file(entry, ec) && !ec.failed())
|
||||
if (boost::filesystem::is_regular_file(*iter, ec) && !ec.failed())
|
||||
{
|
||||
if ((entry.path().string().find(CACHE_FORMAT) != std::string::npos) ||
|
||||
(entry.path().string().find(DB_FORMAT) != std::string::npos))
|
||||
if (((*iter).path().string().find(CACHE_FORMAT) != std::string::npos) ||
|
||||
((*iter).path().string().find(DB_FORMAT) != std::string::npos))
|
||||
{
|
||||
boost::filesystem::remove(entry, ec);
|
||||
boost::filesystem::remove(*iter, ec);
|
||||
if (ec.failed())
|
||||
{
|
||||
LL_WARNS() << "Failed to delete cache file " << entry << ": " << ec.message() << LL_ENDL;
|
||||
LL_WARNS() << "Failed to delete cache file " << *iter << ": " << ec.message() << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
iter.increment(ec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -566,21 +547,21 @@ uintmax_t LLDiskCache::dirFileSize(const std::string dir)
|
|||
#endif
|
||||
if (boost::filesystem::is_directory(dir_path, ec) && !ec.failed())
|
||||
{
|
||||
// <FS:Ansariel> Optimize asset simple disk cache
|
||||
//for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(dir_path, ec), {}))
|
||||
for (auto& entry : boost::make_iterator_range(boost::filesystem::recursive_directory_iterator(dir_path, ec), {}))
|
||||
boost::filesystem::directory_iterator iter(dir_path, ec);
|
||||
while (iter != boost::filesystem::directory_iterator() && !ec.failed())
|
||||
{
|
||||
if (!ec.failed() && (boost::filesystem::is_regular_file(entry, ec) && !ec.failed()))
|
||||
if (boost::filesystem::is_regular_file(*iter, ec) && !ec.failed())
|
||||
{
|
||||
if (entry.path().string().find(mCacheFilenamePrefix) != std::string::npos)
|
||||
if ((*iter).path().string().find(mCacheFilenamePrefix) != std::string::npos)
|
||||
{
|
||||
uintmax_t file_size = boost::filesystem::file_size(entry, ec);
|
||||
uintmax_t file_size = boost::filesystem::file_size(*iter, ec);
|
||||
if (!ec.failed())
|
||||
{
|
||||
total_file_size += file_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
iter.increment(ec);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -827,11 +827,13 @@ void LLFloater::closeFloater(bool app_quitting)
|
|||
}
|
||||
|
||||
// now close dependent floater
|
||||
for(handle_set_iter_t dependent_it = mDependents.begin();
|
||||
dependent_it != mDependents.end(); )
|
||||
while(mDependents.size() > 0)
|
||||
{
|
||||
handle_set_iter_t dependent_it = mDependents.begin();
|
||||
LLFloater* floaterp = dependent_it->get();
|
||||
dependent_it = mDependents.erase(dependent_it);
|
||||
// normally removeDependentFloater will do this, but in
|
||||
// case floaterp is somehow invalid or orphaned, erase now
|
||||
mDependents.erase(dependent_it);
|
||||
if (floaterp)
|
||||
{
|
||||
floaterp->mDependeeHandle = LLHandle<LLFloater>();
|
||||
|
|
|
|||
|
|
@ -215,6 +215,7 @@ NSWindowRef createNSWindow(int x, int y, int width, int height)
|
|||
styleMask:NSTitledWindowMask | NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTexturedBackgroundWindowMask backing:NSBackingStoreBuffered defer:NO];
|
||||
[window makeKeyAndOrderFront:nil];
|
||||
[window setAcceptsMouseMovedEvents:TRUE];
|
||||
[window setRestorable:FALSE]; // Viewer manages state from own settings
|
||||
return window;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4021,42 +4021,48 @@ void LLWindowWin32::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b)
|
|||
|
||||
sLanguageTextInputAllowed = b;
|
||||
|
||||
if ( sLanguageTextInputAllowed )
|
||||
{
|
||||
// Allowing: Restore the previous IME status, so that the user has a feeling that the previous
|
||||
// text input continues naturally. Be careful, however, the IME status is meaningful only during the user keeps
|
||||
// using same Input Locale (aka Keyboard Layout).
|
||||
if (sWinIMEOpened && GetKeyboardLayout(0) == sWinInputLocale)
|
||||
{
|
||||
HIMC himc = LLWinImm::getContext(mWindowHandle);
|
||||
LLWinImm::setOpenStatus(himc, TRUE);
|
||||
LLWinImm::setConversionStatus(himc, sWinIMEConversionMode, sWinIMESentenceMode);
|
||||
LLWinImm::releaseContext(mWindowHandle, himc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Disallowing: Turn off the IME so that succeeding key events bypass IME and come to us directly.
|
||||
// However, do it after saving the current IME status. We need to restore the status when
|
||||
// allowing language text input again.
|
||||
sWinInputLocale = GetKeyboardLayout(0);
|
||||
sWinIMEOpened = LLWinImm::isIME(sWinInputLocale);
|
||||
if (sWinIMEOpened)
|
||||
{
|
||||
HIMC himc = LLWinImm::getContext(mWindowHandle);
|
||||
sWinIMEOpened = LLWinImm::getOpenStatus(himc);
|
||||
if (sWinIMEOpened)
|
||||
{
|
||||
LLWinImm::getConversionStatus(himc, &sWinIMEConversionMode, &sWinIMESentenceMode);
|
||||
if (sLanguageTextInputAllowed)
|
||||
{
|
||||
mWindowThread->post([=]()
|
||||
{
|
||||
// Allowing: Restore the previous IME status, so that the user has a feeling that the previous
|
||||
// text input continues naturally. Be careful, however, the IME status is meaningful only during the user keeps
|
||||
// using same Input Locale (aka Keyboard Layout).
|
||||
if (sWinIMEOpened && GetKeyboardLayout(0) == sWinInputLocale)
|
||||
{
|
||||
HIMC himc = LLWinImm::getContext(mWindowHandle);
|
||||
LLWinImm::setOpenStatus(himc, TRUE);
|
||||
LLWinImm::setConversionStatus(himc, sWinIMEConversionMode, sWinIMESentenceMode);
|
||||
LLWinImm::releaseContext(mWindowHandle, himc);
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
mWindowThread->post([=]()
|
||||
{
|
||||
// Disallowing: Turn off the IME so that succeeding key events bypass IME and come to us directly.
|
||||
// However, do it after saving the current IME status. We need to restore the status when
|
||||
// allowing language text input again.
|
||||
sWinInputLocale = GetKeyboardLayout(0);
|
||||
sWinIMEOpened = LLWinImm::isIME(sWinInputLocale);
|
||||
if (sWinIMEOpened)
|
||||
{
|
||||
HIMC himc = LLWinImm::getContext(mWindowHandle);
|
||||
sWinIMEOpened = LLWinImm::getOpenStatus(himc);
|
||||
if (sWinIMEOpened)
|
||||
{
|
||||
LLWinImm::getConversionStatus(himc, &sWinIMEConversionMode, &sWinIMESentenceMode);
|
||||
|
||||
// We need both ImmSetConversionStatus and ImmSetOpenStatus here to surely disable IME's
|
||||
// keyboard hooking, because Some IME reacts only on the former and some other on the latter...
|
||||
LLWinImm::setConversionStatus(himc, IME_CMODE_NOCONVERSION, sWinIMESentenceMode);
|
||||
LLWinImm::setOpenStatus(himc, FALSE);
|
||||
}
|
||||
LLWinImm::releaseContext(mWindowHandle, himc);
|
||||
}
|
||||
}
|
||||
// We need both ImmSetConversionStatus and ImmSetOpenStatus here to surely disable IME's
|
||||
// keyboard hooking, because Some IME reacts only on the former and some other on the latter...
|
||||
LLWinImm::setConversionStatus(himc, IME_CMODE_NOCONVERSION, sWinIMESentenceMode);
|
||||
LLWinImm::setOpenStatus(himc, FALSE);
|
||||
}
|
||||
LLWinImm::releaseContext(mWindowHandle, himc);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void LLWindowWin32::fillCandidateForm(const LLCoordGL& caret, const LLRect& bounds,
|
||||
|
|
@ -4555,7 +4561,7 @@ BOOL LLWindowWin32::handleImeRequests(WPARAM request, LPARAM param, LRESULT *res
|
|||
LLWString context = find_context(wtext, preedit, preedit_length, &context_offset);
|
||||
preedit -= context_offset;
|
||||
preedit_length = llmin(preedit_length, (S32)context.length() - preedit);
|
||||
if (preedit_length && preedit >= 0)
|
||||
if (preedit_length > 0 && preedit >= 0)
|
||||
{
|
||||
// IMR_DOCUMENTFEED may be called when we have an active preedit.
|
||||
// We should pass the context string *excluding* the preedit string.
|
||||
|
|
|
|||
|
|
@ -6404,7 +6404,8 @@ void LLAppViewer::disconnectViewer()
|
|||
{
|
||||
gInventory.cache(gInventory.getRootFolderID(), gAgent.getID());
|
||||
if (gInventory.getLibraryRootFolderID().notNull()
|
||||
&& gInventory.getLibraryOwnerID().notNull())
|
||||
&& gInventory.getLibraryOwnerID().notNull()
|
||||
&& !mSecondInstance) // agent is unique, library isn't
|
||||
{
|
||||
gInventory.cache(
|
||||
gInventory.getLibraryRootFolderID(),
|
||||
|
|
|
|||
|
|
@ -2931,7 +2931,12 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
|
|||
}
|
||||
else
|
||||
{
|
||||
std::copy(selected_uuid_set.begin(), selected_uuid_set.end(), std::back_inserter(ids));
|
||||
for (std::set<LLFolderViewItem*>::iterator it = selected_items.begin(), end_it = selected_items.end();
|
||||
it != end_it;
|
||||
++it)
|
||||
{
|
||||
ids.push_back(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
|
||||
}
|
||||
}
|
||||
|
||||
// Check for actions that get handled in bulk
|
||||
|
|
|
|||
|
|
@ -2146,18 +2146,20 @@ void LLInventoryModel::cache(
|
|||
items,
|
||||
INCLUDE_TRASH,
|
||||
can_cache);
|
||||
std::string inventory_filename = getInvCacheAddres(agent_id);
|
||||
saveToFile(inventory_filename, categories, items);
|
||||
std::string gzip_filename(inventory_filename);
|
||||
// Use temporary file to avoid potential conflicts with other
|
||||
// instances (even a 'read only' instance unzips into a file)
|
||||
std::string temp_file = gDirUtilp->getTempFilename();
|
||||
saveToFile(temp_file, categories, items);
|
||||
std::string gzip_filename = getInvCacheAddres(agent_id);
|
||||
gzip_filename.append(".gz");
|
||||
if(gzip_file(inventory_filename, gzip_filename))
|
||||
if(gzip_file(temp_file, gzip_filename))
|
||||
{
|
||||
LL_DEBUGS(LOG_INV) << "Successfully compressed " << inventory_filename << LL_ENDL;
|
||||
LLFile::remove(inventory_filename);
|
||||
LL_DEBUGS(LOG_INV) << "Successfully compressed " << temp_file << " to " << gzip_filename << LL_ENDL;
|
||||
LLFile::remove(temp_file);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS(LOG_INV) << "Unable to compress " << inventory_filename << LL_ENDL;
|
||||
LL_WARNS(LOG_INV) << "Unable to compress " << temp_file << " into " << gzip_filename << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3319,6 +3321,7 @@ bool LLInventoryModel::saveToFile(const std::string& filename,
|
|||
return false;
|
||||
}
|
||||
}
|
||||
fileXML.flush();
|
||||
|
||||
fileXML.close();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue