#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
/* 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: