diff options
Diffstat (limited to 'compat')
| -rw-r--r-- | compat/run-in-thread.hpp | 90 | 
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>  | 
