diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2017-02-27 10:55:37 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2017-02-27 10:55:37 +0100 |
commit | 1b01642dda7ae8bbf3e74a979ffcf7941a8ae2b9 (patch) | |
tree | 8245eb2a18183181ee766384c3a4e43cec559e34 /options | |
parent | 99ab4eb8e64bdc7abe0a8751ada04342f21884f2 (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.cpp | 49 | ||||
-rw-r--r-- | options/bundle.hpp | 9 |
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(); }; |