#pragma once /* Copyright (c) 2016 Stanislaw Halik * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. */ #include #include #include #include #include namespace impl_run_in_thread { struct semaphore final { using lock_guard = std::unique_lock; 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(); } }; } template void run_in_thread_sync(QObject* obj, F&& fun) { if (obj->thread() == QThread::currentThread()) return (void)fun(); impl_run_in_thread::semaphore sem; { QObject src; QObject::connect(&src, &QObject::destroyed, obj, [&] { fun(); sem.notify(); }, Qt::QueuedConnection); } sem.wait(); } template void run_in_thread_async(QObject* obj, F&& fun) { if (obj->thread() == QThread::currentThread()) return (void)fun(); QObject src; QObject::connect(&src, &QObject::destroyed, obj, std::forward(fun), Qt::QueuedConnection); }