diff options
author | Sven Gothel <[email protected]> | 2022-05-13 01:26:43 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2022-05-13 01:26:43 +0200 |
commit | e6ada6040b738df03c8cc6199a6375cf3aa67e44 (patch) | |
tree | c57848ba437f35fb564646830248ba0a40830b1d /include | |
parent | e5421ff1dfed4d26ac40542252aba0c4bb1094b5 (diff) |
Fix call_on_release: Skip calling `release_func` if resource has been marked orderly released, avoid use after free.
Detected via valgrind.
Diffstat (limited to 'include')
-rw-r--r-- | include/jau/basic_algos.hpp | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/include/jau/basic_algos.hpp b/include/jau/basic_algos.hpp index 10efa69..569f48a 100644 --- a/include/jau/basic_algos.hpp +++ b/include/jau/basic_algos.hpp @@ -49,27 +49,38 @@ namespace jau { * jau::relaxed_atomic_bool is_running = true; * * void some_thread_func() { - * thread_local jau::call_on_release lili([&]() { + * thread_local jau::call_on_release thread_cleanup([&]() { * is_running = false; * }); * ... * do some work here, which might get cancelled * .. + * thread_cleanup.set_released(); // mark orderly release * } * </pre> * </p> * @tparam UnaryFunction user provided function to be called @ dtor + * @see jau::service_runner */ template <class UnaryFunction> class call_on_release { private: UnaryFunction f; + jau::sc_atomic_bool released; public: - call_on_release(UnaryFunction release_func) noexcept : f(release_func) {} - ~call_on_release() noexcept { f(); } + call_on_release(UnaryFunction release_func) noexcept + : f(release_func), released(false) {} + ~call_on_release() noexcept { + if( !released ) { f(); } + } call_on_release(const call_on_release&) = delete; call_on_release& operator=(const call_on_release&) = delete; call_on_release& operator=(const call_on_release&) volatile = delete; + + /** Mark the resource being orderly released, `release_func()` will not be called and *use after free* avoided. */ + void set_released() noexcept { released = true; } + /** Query whethr the resource has been orderly released. */ + bool is_released() const noexcept { return released; } }; /**************************************************************************************** |