diff options
Diffstat (limited to 'gdbsupport/thread-pool.h')
-rw-r--r-- | gdbsupport/thread-pool.h | 76 |
1 files changed, 71 insertions, 5 deletions
diff --git a/gdbsupport/thread-pool.h b/gdbsupport/thread-pool.h index 5e203fd..4db35ba 100644 --- a/gdbsupport/thread-pool.h +++ b/gdbsupport/thread-pool.h @@ -27,13 +27,70 @@ #include <thread> #include <mutex> #include <condition_variable> -#endif #include <future> +#endif #include "gdbsupport/gdb_optional.h" namespace gdb { +#if CXX_STD_THREAD + +/* Simply use the standard future. */ +template<typename T> +using future = std::future<T>; + +#else /* CXX_STD_THREAD */ + +/* A compatibility wrapper for std::future. Once <thread> and + <future> are available in all GCC builds -- should that ever happen + -- this can be removed. GCC does not implement threading for + MinGW, see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93687. + + Meanwhile, in this mode, there are no threads. Tasks submitted to + the thread pool are invoked immediately and their result is stored + here. The base template here simply wraps a T and provides some + std::future compatibility methods. The provided methods are chosen + based on what GDB needs presently. */ + +template<typename T> +class future +{ +public: + + explicit future (T value) + : m_value (std::move (value)) + { + } + + future () = default; + future (future &&other) = default; + future (const future &other) = delete; + future &operator= (future &&other) = default; + future &operator= (const future &other) = delete; + + void wait () const { } + + T get () { return std::move (m_value); } + +private: + + T m_value; +}; + +/* A specialization for void. */ + +template<> +class future<void> +{ +public: + void wait () const { } + void get () { } +}; + +#endif /* CXX_STD_THREAD */ + + /* A thread pool. There is a single global thread pool, see g_thread_pool. Tasks can @@ -64,23 +121,32 @@ public: /* Post a task to the thread pool. A future is returned, which can be used to wait for the result. */ - std::future<void> post_task (std::function<void ()> &&func) + future<void> post_task (std::function<void ()> &&func) { +#if CXX_STD_THREAD std::packaged_task<void ()> task (std::move (func)); - std::future<void> result = task.get_future (); + future<void> result = task.get_future (); do_post_task (std::packaged_task<void ()> (std::move (task))); return result; +#else + func (); + return {}; +#endif /* CXX_STD_THREAD */ } /* Post a task to the thread pool. A future is returned, which can be used to wait for the result. */ template<typename T> - std::future<T> post_task (std::function<T ()> &&func) + future<T> post_task (std::function<T ()> &&func) { +#if CXX_STD_THREAD std::packaged_task<T ()> task (std::move (func)); - std::future<T> result = task.get_future (); + future<T> result = task.get_future (); do_post_task (std::packaged_task<void ()> (std::move (task))); return result; +#else + return future<T> (func ()); +#endif /* CXX_STD_THREAD */ } private: |