summaryrefslogtreecommitdiffhomepage
path: root/options
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2017-02-27 10:55:37 +0100
committerStanislaw Halik <sthalik@misaki.pl>2017-02-27 10:55:37 +0100
commit1b01642dda7ae8bbf3e74a979ffcf7941a8ae2b9 (patch)
tree8245eb2a18183181ee766384c3a4e43cec559e34 /options
parent99ab4eb8e64bdc7abe0a8751ada04342f21884f2 (diff)
options/fix bundle refcount handling
We rolled up our own refcount while using shared_ptr at the same time. Remove all rolled-up logic and rely on shared_ptr's custom deleter to do the cleanups. This greatly simplifies the code here. Unfortunately, _fini ordering makes Qt crash after the app object runs out of scope: gui/main.cpp: QApplication app(argc, argv); Both things considered, use _exit(2) on Unix to avoid running static destructors.
Diffstat (limited to 'options')
-rw-r--r--options/bundle.cpp49
-rw-r--r--options/bundle.hpp9
2 files changed, 28 insertions, 30 deletions
diff --git a/options/bundle.cpp b/options/bundle.cpp
index 74e08eb9..1eb69b60 100644
--- a/options/bundle.cpp
+++ b/options/bundle.cpp
@@ -126,18 +126,6 @@ bool bundle::is_modified() const
return false;
}
-void bundler::bundle_decf(const bundler::k& key)
-{
- QMutexLocker l(&implsgl_mtx);
-
- if (--std::get<0>(implsgl_data[key]) == 0)
- {
- //qDebug() << "bundle -" << key;
-
- implsgl_data.erase(key);
- }
-}
-
void bundler::after_profile_changed_()
{
QMutexLocker l(&implsgl_mtx);
@@ -146,10 +134,8 @@ void bundler::after_profile_changed_()
for (auto& kv : implsgl_data)
{
- tt& tuple = kv.second;
- std::weak_ptr<v>& bundle = std::get<1>(tuple);
-
- mem<v> bundle_ = bundle.lock();
+ weak bundle = kv.second;
+ shared bundle_ = bundle.lock();
if (bundle_)
{
//qDebug() << "bundle: reverting" << kv.first << "due to profile change";
@@ -169,25 +155,36 @@ bundler::bundler() : implsgl_mtx(QMutex::Recursive)
bundler::~bundler()
{
- qDebug() << "exit: bundle singleton";
+ //qDebug() << "exit: bundle singleton";
}
-std::shared_ptr<bundler::v> bundler::make_bundle(const bundler::k &key)
+std::shared_ptr<bundler::v> bundler::make_bundle(const bundler::k& key)
{
QMutexLocker l(&implsgl_mtx);
- if (implsgl_data.count(key) != 0)
+ auto it = implsgl_data.find(key);
+
+ if (it != implsgl_data.end())
{
- auto shared = std::get<1>(implsgl_data[key]).lock();
- if (shared != nullptr)
- return shared;
+ std::shared_ptr<v> ptr = it->second.lock();
+ if (ptr != nullptr)
+ return ptr;
+ else
+ qDebug() << "ERROR: nonexistent bundle" << key;
}
- //qDebug() << "bundle +" << key;
+ auto shr = shared(new v(key), [this, key](v* ptr) {
+ QMutexLocker l(&implsgl_mtx);
- std::shared_ptr<v> shr(new v(key), [this](v* val) { bundle_decf(val->name()); });
- implsgl_data[key] = tt(1, shr);
+ auto it = implsgl_data.find(key);
+ if (it != implsgl_data.end())
+ implsgl_data.erase(it);
+ else
+ qDebug() << "ERROR: can't find self-bundle!";
+ delete ptr;
+ });
+ implsgl_data[key] = weak(shr);
return shr;
}
@@ -204,7 +201,7 @@ OPENTRACK_OPTIONS_EXPORT std::shared_ptr<bundle_> make_bundle(const QString& nam
if (name.size())
return detail::singleton().make_bundle(name);
else
- return std::make_shared<bundle_>(QStringLiteral(""));
+ return std::make_shared<bundle_>(QString());
}
QMutex* options::detail::bundle::get_mtx() const { return mtx; }
diff --git a/options/bundle.hpp b/options/bundle.hpp
index 3d952928..c8050ec7 100644
--- a/options/bundle.hpp
+++ b/options/bundle.hpp
@@ -81,22 +81,23 @@ public:
}
};
+OPENTRACK_OPTIONS_EXPORT bundler& singleton();
+
struct OPENTRACK_OPTIONS_EXPORT bundler
{
public:
using k = QString;
using v = bundle;
- using cnt = int;
- using tt = std::tuple<cnt, std::weak_ptr<v>>;
+ using weak = std::weak_ptr<v>;
+ using shared = std::shared_ptr<v>;
private:
QMutex implsgl_mtx;
- std::map<k, tt> implsgl_data;
+ std::map<k, weak> implsgl_data;
void after_profile_changed_();
public:
bundler();
~bundler();
std::shared_ptr<v> make_bundle(const k& key);
- void bundle_decf(const k& key);
static void refresh_all_bundles();
};