summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/directoryrefresher.cpp65
-rw-r--r--src/directoryrefresher.h2
-rw-r--r--src/organizercore.cpp68
-rw-r--r--src/organizercore.h2
-rw-r--r--src/shared/directoryentry.cpp48
-rw-r--r--src/shared/directoryentry.h3
6 files changed, 80 insertions, 108 deletions
diff --git a/src/directoryrefresher.cpp b/src/directoryrefresher.cpp
index a59ddf9d..cb5bfc5b 100644
--- a/src/directoryrefresher.cpp
+++ b/src/directoryrefresher.cpp
@@ -48,7 +48,7 @@ DirectoryRefresher::~DirectoryRefresher()
delete m_DirectoryStructure;
}
-DirectoryEntry *DirectoryRefresher::getDirectoryStructure()
+DirectoryEntry *DirectoryRefresher::stealDirectoryStructure()
{
QMutexLocker locker(&m_RefreshLock);
DirectoryEntry *result = m_DirectoryStructure;
@@ -279,58 +279,50 @@ void DirectoryRefresher::addMultipleModsFilesToStructure(
g_threads.setMax(m_threadCount);
- {
- TimeThis tt("walk dirs");
-
- for (std::size_t i=0; i<entries.size(); ++i) {
- const auto& e = entries[i];
- const int prio = static_cast<int>(i + 1);
+ for (std::size_t i=0; i<entries.size(); ++i) {
+ const auto& e = entries[i];
+ const int prio = static_cast<int>(i + 1);
- stats[i].mod = entries[i].modName.toStdString();
-
- try
- {
- if (e.stealFiles.length() > 0) {
- stealModFilesIntoStructure(
- directoryStructure, e.modName, prio, e.absolutePath, e.stealFiles);
- } else {
- auto& mt = g_threads.request();
+ stats[i].mod = entries[i].modName.toStdString();
- mt.ds = directoryStructure;
- mt.modName = entries[i].modName.toStdWString();
- mt.path = QDir::toNativeSeparators(e.absolutePath).toStdWString();
- mt.prio = prio;
- mt.stats = &stats[i];
+ try
+ {
+ if (e.stealFiles.length() > 0) {
+ stealModFilesIntoStructure(
+ directoryStructure, e.modName, prio, e.absolutePath, e.stealFiles);
+ } else {
+ auto& mt = g_threads.request();
- mt.wakeup();
- }
- } catch (const std::exception& ex) {
- emit error(tr("failed to read mod (%1): %2").arg(e.modName, ex.what()));
- }
+ mt.ds = directoryStructure;
+ mt.modName = entries[i].modName.toStdWString();
+ mt.path = QDir::toNativeSeparators(e.absolutePath).toStdWString();
+ mt.prio = prio;
+ mt.stats = &stats[i];
- if (emitProgress) {
- emit progress((static_cast<int>(i) * 100) / static_cast<int>(entries.size()) + 1);
+ mt.wakeup();
}
+ } catch (const std::exception& ex) {
+ emit error(tr("failed to read mod (%1): %2").arg(e.modName, ex.what()));
}
- g_threads.waitForAll();
+ if (emitProgress) {
+ emit progress((static_cast<int>(i) * 100) / static_cast<int>(entries.size()) + 1);
+ }
}
+ g_threads.waitForAll();
+
dumpStats(stats);
}
-namespace MOShared{ void logcounts(std::string w); }
-
void DirectoryRefresher::refresh()
{
SetThisThreadName("DirectoryRefresher");
+ TimeThis tt("refresh");
for (int i=0; i<1; ++i) {
QMutexLocker locker(&m_RefreshLock);
-
- //logcounts("before delete");
delete m_DirectoryStructure;
- //logcounts("after delete");
m_DirectoryStructure = new DirectoryEntry(L"data", nullptr, 0);
@@ -355,9 +347,6 @@ void DirectoryRefresher::refresh()
cleanStructure(m_DirectoryStructure);
}
- emit progress(100);
-
+ emit progress(100);
emit refreshed();
-
- //logcounts("after refresh");
}
diff --git a/src/directoryrefresher.h b/src/directoryrefresher.h
index c531ba39..18bfed4d 100644
--- a/src/directoryrefresher.h
+++ b/src/directoryrefresher.h
@@ -67,7 +67,7 @@ public:
*
* @return updated directory structure
**/
- MOShared::DirectoryEntry *getDirectoryStructure();
+ MOShared::DirectoryEntry* stealDirectoryStructure();
/**
* @brief sets up the mods to be included in the directory structure
diff --git a/src/organizercore.cpp b/src/organizercore.cpp
index 86abeb35..a3202153 100644
--- a/src/organizercore.cpp
+++ b/src/organizercore.cpp
@@ -144,6 +144,10 @@ OrganizerCore::~OrganizerCore()
m_RefresherThread.exit();
m_RefresherThread.wait();
+ if (m_StructureDeleter.joinable()) {
+ m_StructureDeleter.join();
+ }
+
saveCurrentProfile();
// profile has to be cleaned up before the modinfo-buffer is cleared
@@ -1379,46 +1383,74 @@ std::vector<QString> OrganizerCore::enabledArchives()
void OrganizerCore::refreshDirectoryStructure()
{
- if (!m_DirectoryUpdate) {
- m_CurrentProfile->writeModlistNow(true);
+ if (m_DirectoryUpdate) {
+ log::debug("can't refresh, already in progress");
+ return;
+ }
- m_DirectoryUpdate = true;
- std::vector<std::tuple<QString, QString, int>> activeModList
- = m_CurrentProfile->getActiveMods();
- auto archives = enabledArchives();
- m_DirectoryRefresher.setMods(
- activeModList, std::set<QString>(archives.begin(), archives.end()));
+ log::debug("refreshing structure");
+ m_DirectoryUpdate = true;
- QTimer::singleShot(0, &m_DirectoryRefresher, SLOT(refresh()));
- }
+ m_CurrentProfile->writeModlistNow(true);
+ const auto activeModList = m_CurrentProfile->getActiveMods();
+ const auto archives = enabledArchives();
+
+ m_DirectoryRefresher.setMods(
+ activeModList, std::set<QString>(archives.begin(), archives.end()));
+
+ // runs refresh() in a thread
+ QTimer::singleShot(0, &m_DirectoryRefresher, SLOT(refresh()));
}
void OrganizerCore::directory_refreshed()
{
- DirectoryEntry *newStructure = m_DirectoryRefresher.getDirectoryStructure();
+ log::debug("structure refreshed");
+
+ DirectoryEntry *newStructure = m_DirectoryRefresher.stealDirectoryStructure();
Q_ASSERT(newStructure != m_DirectoryStructure);
- if (newStructure != nullptr) {
- std::swap(m_DirectoryStructure, newStructure);
- delete newStructure;
- } else {
+
+ if (newStructure == nullptr) {
// TODO: don't know why this happens, this slot seems to get called twice
// with only one emit
return;
}
+
+ std::swap(m_DirectoryStructure, newStructure);
+
+ if (m_StructureDeleter.joinable()) {
+ m_StructureDeleter.join();
+ }
+
+ m_StructureDeleter = std::thread([=]{
+ log::debug("structure deleter thread start");
+ delete newStructure;
+ log::debug("structure deleter thread done");
+ });
+
m_DirectoryUpdate = false;
+ log::debug("clearing caches");
for (int i = 0; i < m_ModList.rowCount(); ++i) {
ModInfo::Ptr modInfo = ModInfo::getByIndex(i);
modInfo->clearCaches();
}
- for (auto task : m_PostRefreshTasks) {
- task();
+
+ if (!m_PostRefreshTasks.empty()) {
+ log::debug("running {} post refresh tasks", m_PostRefreshTasks.size());
+
+ for (auto task : m_PostRefreshTasks) {
+ task();
+ }
+
+ m_PostRefreshTasks.clear();
}
- m_PostRefreshTasks.clear();
if (m_CurrentProfile != nullptr) {
+ log::debug("refreshing lists");
refreshLists();
}
+
+ log::debug("refresh done");
}
void OrganizerCore::profileRefresh()
diff --git a/src/organizercore.h b/src/organizercore.h
index a63dc959..223eb6cb 100644
--- a/src/organizercore.h
+++ b/src/organizercore.h
@@ -346,6 +346,8 @@ private:
QThread m_RefresherThread;
+ std::thread m_StructureDeleter;
+
bool m_DirectoryUpdate;
bool m_ArchivesInit;
bool m_ArchiveParsing{ m_Settings.archiveParsing() };
diff --git a/src/shared/directoryentry.cpp b/src/shared/directoryentry.cpp
index 4e64d1c1..c5702026 100644
--- a/src/shared/directoryentry.cpp
+++ b/src/shared/directoryentry.cpp
@@ -40,13 +40,6 @@ namespace MOShared
using namespace MOBase;
static const int MAXPATH_UNICODE = 32767;
-
-static std::atomic<int> FileEntryCount(0);
-static std::atomic<int> FilesOriginCount(0);
-static std::atomic<int> FileRegisterCount(0);
-static std::atomic<int> DirectoryEntryCount(0);
-static std::atomic<int> OriginConnectionCount(0);
-
template <class F>
std::chrono::nanoseconds elapsed(F&& f)
{
@@ -56,13 +49,6 @@ std::chrono::nanoseconds elapsed(F&& f)
return (end - start);
}
-void logcounts(std::string w)
-{
- log::debug(
- "{}: FileEntry={} FilesOrigin={} FileRegister={} DirectoryEntry={} OriginConnection={}",
- w, FileEntryCount, FilesOriginCount, FileRegisterCount, DirectoryEntryCount, OriginConnectionCount);
-}
-
static std::wstring tail(const std::wstring &source, const size_t count)
{
@@ -203,12 +189,6 @@ public:
OriginConnection()
: m_NextID(0)
{
- ++OriginConnectionCount;
- }
-
- ~OriginConnection()
- {
- --OriginConnectionCount;
}
std::pair<FilesOrigin&, bool> getOrCreate(
@@ -350,7 +330,6 @@ FileEntry::FileEntry() :
m_FileSize(NoFileSize), m_CompressedFileSize(NoFileSize),
m_LastAccessed(time(nullptr))
{
- ++FileEntryCount;
}
FileEntry::FileEntry(Index index, std::wstring name, DirectoryEntry *parent) :
@@ -358,16 +337,6 @@ FileEntry::FileEntry(Index index, std::wstring name, DirectoryEntry *parent) :
m_FileSize(NoFileSize), m_CompressedFileSize(NoFileSize),
m_LastAccessed(time(nullptr))
{
- ++FileEntryCount;
-}
-
-FileEntry::~FileEntry()
-{
- while (!m_Alternatives.empty()) {
- m_Alternatives.pop_back();
- }
-
- --FileEntryCount;
}
void FileEntry::addOrigin(
@@ -606,7 +575,6 @@ bool FileEntry::recurseParents(std::wstring &path, const DirectoryEntry *parent)
FilesOrigin::FilesOrigin()
: m_ID(0), m_Disabled(false), m_Name(), m_Path(), m_Priority(0)
{
- ++FilesOriginCount;
}
FilesOrigin::FilesOrigin(const FilesOrigin &reference)
@@ -618,7 +586,6 @@ FilesOrigin::FilesOrigin(const FilesOrigin &reference)
, m_FileRegister(reference.m_FileRegister)
, m_OriginConnection(reference.m_OriginConnection)
{
- ++FilesOriginCount;
}
FilesOrigin::FilesOrigin(
@@ -629,12 +596,6 @@ FilesOrigin::FilesOrigin(
m_Priority(priority), m_FileRegister(fileRegister),
m_OriginConnection(originConnection)
{
- ++FilesOriginCount;
-}
-
-FilesOrigin::~FilesOrigin()
-{
- --FilesOriginCount;
}
void FilesOrigin::setPriority(int priority)
@@ -733,12 +694,6 @@ bool FilesOrigin::containsArchive(std::wstring archiveName)
FileRegister::FileRegister(boost::shared_ptr<OriginConnection> originConnection)
: m_OriginConnection(originConnection)
{
- ++FileRegisterCount;
-}
-
-FileRegister::~FileRegister()
-{
- --FileRegisterCount;
}
bool FileRegister::indexValid(FileEntry::Index index) const
@@ -907,7 +862,6 @@ DirectoryEntry::DirectoryEntry(
m_OriginConnection(new OriginConnection),
m_Name(std::move(name)), m_Parent(parent), m_Populated(false), m_TopLevel(true)
{
- ++DirectoryEntryCount;
m_FileRegister.reset(new FileRegister(m_OriginConnection));
m_Origins.insert(originID);
}
@@ -919,13 +873,11 @@ DirectoryEntry::DirectoryEntry(
m_FileRegister(fileRegister), m_OriginConnection(originConnection),
m_Name(std::move(name)), m_Parent(parent), m_Populated(false), m_TopLevel(false)
{
- ++DirectoryEntryCount;
m_Origins.insert(originID);
}
DirectoryEntry::~DirectoryEntry()
{
- --DirectoryEntryCount;
clear();
}
diff --git a/src/shared/directoryentry.h b/src/shared/directoryentry.h
index 2a70d486..94ea068d 100644
--- a/src/shared/directoryentry.h
+++ b/src/shared/directoryentry.h
@@ -121,7 +121,6 @@ public:
FileEntry();
FileEntry(Index index, std::wstring name, DirectoryEntry *parent);
- ~FileEntry();
Index getIndex() const
{
@@ -237,7 +236,6 @@ class FilesOrigin
public:
FilesOrigin();
FilesOrigin(const FilesOrigin &reference);
- ~FilesOrigin();
// sets priority for this origin, but it will overwrite the existing mapping
// for this priority, the previous origin will no longer be referenced
@@ -307,7 +305,6 @@ class FileRegister
{
public:
FileRegister(boost::shared_ptr<OriginConnection> originConnection);
- ~FileRegister();
bool indexValid(FileEntry::Index index) const;