summaryrefslogtreecommitdiffhomepage
path: root/compat/run-in-thread.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'compat/run-in-thread.hpp')
-rw-r--r--compat/run-in-thread.hpp90
1 files changed, 25 insertions, 65 deletions
diff --git a/compat/run-in-thread.hpp b/compat/run-in-thread.hpp
index afb41c98..c552c600 100644
--- a/compat/run-in-thread.hpp
+++ b/compat/run-in-thread.hpp
@@ -7,9 +7,6 @@
* copyright notice and this permission notice appear in all copies.
*/
-#include "macros.hpp"
-
-#include <cassert>
#include <thread>
#include <condition_variable>
#include <utility>
@@ -17,85 +14,48 @@
#include <QObject>
#include <QThread>
-namespace qt_impl_detail {
-
-template<typename u>
-struct run_in_thread_traits
+namespace impl_run_in_thread {
+struct semaphore final
{
- using ret_type = std::remove_reference_t<u>;
-
- template<typename t>
- static inline void assign(u& lvalue, t&& rvalue) { std::forward<u>(lvalue) = std::forward<t>(rvalue); }
+ using lock_guard = std::unique_lock<std::mutex>;
+ std::mutex mtx;
+ std::condition_variable cvar;
+ bool flag = false;
- template<typename t>
- static inline auto pass(t&& val) -> decltype(auto) { return std::forward<t>(val); }
+ semaphore() = default;
- template<typename F> static inline auto call(F&& fun) -> decltype(auto) { return std::forward<F>(fun)(); }
-};
+ void wait()
+ {
+ lock_guard guard(mtx);
+ while (!flag)
+ cvar.wait(guard);
+ }
-template<>
-struct run_in_thread_traits<void>
-{
- using type = unsigned char;
- using ret_type = void;
- static inline void assign(unsigned char&, unsigned char) {}
- static inline void pass(type) {}
- template<typename F> static type call(F&& fun) { std::forward<F>(fun)(); return type(0); }
+ void notify()
+ {
+ lock_guard guard(mtx);
+ flag = true;
+ cvar.notify_one();
+ }
};
-
}
template<typename F>
-auto never_inline
-run_in_thread_sync(QObject* obj, F&& fun)
- -> typename qt_impl_detail::run_in_thread_traits<decltype(fun())>::ret_type
+void run_in_thread_sync(QObject* obj, F&& fun)
{
- using lock_guard = std::unique_lock<std::mutex>;
-
- using traits = qt_impl_detail::run_in_thread_traits<decltype(fun())>;
-
- typename traits::type ret;
-
- struct semaphore final
- {
- std::mutex mtx;
- std::condition_variable cvar;
- bool flag = false;
-
- semaphore() = default;
-
- void wait()
- {
- lock_guard guard(mtx);
- while (!flag)
- cvar.wait(guard);
- }
-
- void notify()
- {
- lock_guard guard(mtx);
- flag = true;
- cvar.notify_one();
- }
- };
-
if (obj->thread() == QThread::currentThread())
- return traits::pass(traits::call(fun));
+ return (void)fun();
- semaphore sem;
+ impl_run_in_thread::semaphore sem;
{
QObject src;
- src.moveToThread(QThread::currentThread());
- QObject::connect(&src, &QObject::destroyed, obj, [&] {
- traits::assign(ret, traits::call(fun));
- sem.notify();
- },
- Qt::QueuedConnection);
+ QObject::connect(&src, &QObject::destroyed,
+ obj, [&] { fun(); sem.notify(); },
+ Qt::QueuedConnection);
}
sem.wait();
- return traits::pass(std::move(ret));
}
template<typename F>