fix async redefined
This commit is contained in:
@ -19,7 +19,7 @@
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef ASYNCXX_H_
|
||||
# error "Do not include this header directly, include <async++.h> instead."
|
||||
#error "Do not include this header directly, include <async++.h> instead."
|
||||
#endif
|
||||
|
||||
namespace async {
|
||||
@ -31,54 +31,51 @@ LIBASYNC_EXPORT std::size_t hardware_concurrency() LIBASYNC_NOEXCEPT;
|
||||
|
||||
// Task handle used by a wait handler
|
||||
class task_wait_handle {
|
||||
detail::task_base* handle;
|
||||
detail::task_base *handle;
|
||||
|
||||
// Allow construction in wait_for_task()
|
||||
friend LIBASYNC_EXPORT void detail::wait_for_task(detail::task_base* t);
|
||||
task_wait_handle(detail::task_base* t)
|
||||
: handle(t) {}
|
||||
// Allow construction in wait_for_task()
|
||||
friend void detail::wait_for_task(detail::task_base *t);
|
||||
friend void detail::generic_wait_for_task(detail::task_base *wait_task);
|
||||
|
||||
// Execution function for use by wait handlers
|
||||
template<typename Func>
|
||||
struct wait_exec_func: private detail::func_base<Func> {
|
||||
template<typename F>
|
||||
explicit wait_exec_func(F&& f)
|
||||
: detail::func_base<Func>(std::forward<F>(f)) {}
|
||||
void operator()(detail::task_base*)
|
||||
{
|
||||
// Just call the function directly, all this wrapper does is remove
|
||||
// the task_base* parameter.
|
||||
this->get_func()();
|
||||
}
|
||||
};
|
||||
task_wait_handle(detail::task_base *t) : handle(t) {}
|
||||
|
||||
// Execution function for use by wait handlers
|
||||
template<typename Func>
|
||||
struct wait_exec_func : private detail::func_base<Func> {
|
||||
template<typename F>
|
||||
explicit wait_exec_func(F &&f) : detail::func_base<Func>(std::forward<F>(f))
|
||||
{}
|
||||
|
||||
void operator()(detail::task_base *)
|
||||
{
|
||||
// Just call the function directly, all this wrapper does is remove
|
||||
// the task_base* parameter.
|
||||
this->get_func()();
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
task_wait_handle()
|
||||
: handle(nullptr) {}
|
||||
task_wait_handle() : handle(nullptr) {}
|
||||
|
||||
// Check if the handle is valid
|
||||
explicit operator bool() const
|
||||
{
|
||||
return handle != nullptr;
|
||||
}
|
||||
// Check if the handle is valid
|
||||
explicit operator bool() const { return handle != nullptr; }
|
||||
|
||||
// Check if the task has finished executing
|
||||
bool ready() const
|
||||
{
|
||||
return detail::is_finished(handle->state.load(std::memory_order_acquire));
|
||||
}
|
||||
// Check if the task has finished executing
|
||||
bool ready() const { return detail::is_finished(handle->state.load(std::memory_order_acquire)); }
|
||||
|
||||
// Queue a function to be executed when the task has finished executing.
|
||||
template<typename Func>
|
||||
void on_finish(Func&& func)
|
||||
{
|
||||
// Make sure the function type is callable
|
||||
static_assert(detail::is_callable<Func()>::value, "Invalid function type passed to on_finish()");
|
||||
// Queue a function to be executed when the task has finished executing.
|
||||
template<typename Func>
|
||||
void on_finish(Func &&func)
|
||||
{
|
||||
// Make sure the function type is callable
|
||||
static_assert(detail::is_callable<Func()>::value, "Invalid function type passed to on_finish()");
|
||||
|
||||
auto cont = new detail::task_func<typename std::remove_reference<decltype(inline_scheduler())>::type, wait_exec_func<typename std::decay<Func>::type>, detail::fake_void>(std::forward<Func>(func));
|
||||
cont->sched = std::addressof(inline_scheduler());
|
||||
handle->add_continuation(inline_scheduler(), detail::task_ptr(cont));
|
||||
}
|
||||
auto cont = new detail::task_func<typename std::remove_reference<decltype(inline_scheduler())>::type,
|
||||
wait_exec_func<typename std::decay<Func>::type>,
|
||||
detail::fake_void>(std::forward<Func>(func));
|
||||
cont->sched = std::addressof(inline_scheduler());
|
||||
handle->add_continuation(inline_scheduler(), detail::task_ptr(cont));
|
||||
}
|
||||
};
|
||||
|
||||
// Wait handler function prototype
|
||||
@ -95,81 +92,78 @@ struct LIBASYNC_EXPORT_EXCEPTION task_not_executed {};
|
||||
|
||||
// Task handle used in scheduler, acts as a unique_ptr to a task object
|
||||
class task_run_handle {
|
||||
detail::task_ptr handle;
|
||||
detail::task_ptr handle;
|
||||
|
||||
// Allow construction in schedule_task()
|
||||
template<typename Sched>
|
||||
friend void detail::schedule_task(Sched& sched, detail::task_ptr t);
|
||||
explicit task_run_handle(detail::task_ptr t)
|
||||
: handle(std::move(t)) {}
|
||||
// Allow construction in schedule_task()
|
||||
template<typename Sched>
|
||||
friend void detail::schedule_task(Sched &sched, detail::task_ptr t);
|
||||
|
||||
explicit task_run_handle(detail::task_ptr t) : handle(std::move(t)) {}
|
||||
|
||||
public:
|
||||
// Movable but not copyable
|
||||
task_run_handle() = default;
|
||||
task_run_handle(task_run_handle&& other) LIBASYNC_NOEXCEPT
|
||||
: handle(std::move(other.handle)) {}
|
||||
task_run_handle& operator=(task_run_handle&& other) LIBASYNC_NOEXCEPT
|
||||
{
|
||||
handle = std::move(other.handle);
|
||||
return *this;
|
||||
}
|
||||
// Movable but not copyable
|
||||
task_run_handle() = default;
|
||||
|
||||
// If the task is not executed, cancel it with an exception
|
||||
~task_run_handle()
|
||||
{
|
||||
if (handle)
|
||||
handle->vtable->cancel(handle.get(), std::make_exception_ptr(task_not_executed()));
|
||||
}
|
||||
task_run_handle(task_run_handle &&other) LIBASYNC_NOEXCEPT : handle(std::move(other.handle)) {}
|
||||
|
||||
// Check if the handle is valid
|
||||
explicit operator bool() const
|
||||
{
|
||||
return handle != nullptr;
|
||||
}
|
||||
task_run_handle &operator=(task_run_handle &&other) LIBASYNC_NOEXCEPT
|
||||
{
|
||||
handle = std::move(other.handle);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Run the task and release the handle
|
||||
void run()
|
||||
{
|
||||
handle->vtable->run(handle.get());
|
||||
handle = nullptr;
|
||||
}
|
||||
// If the task is not executed, cancel it with an exception
|
||||
~task_run_handle()
|
||||
{
|
||||
if (handle) handle->vtable->cancel(handle.get(), std::make_exception_ptr(task_not_executed()));
|
||||
}
|
||||
|
||||
// Run the task but run the given wait handler when waiting for a task,
|
||||
// instead of just sleeping.
|
||||
void run_with_wait_handler(wait_handler handler)
|
||||
{
|
||||
wait_handler old = set_thread_wait_handler(handler);
|
||||
run();
|
||||
set_thread_wait_handler(old);
|
||||
}
|
||||
// Check if the handle is valid
|
||||
explicit operator bool() const { return handle != nullptr; }
|
||||
|
||||
// Conversion to and from void pointer. This allows the task handle to be
|
||||
// sent through C APIs which don't preserve types.
|
||||
void* to_void_ptr()
|
||||
{
|
||||
return handle.release();
|
||||
}
|
||||
static task_run_handle from_void_ptr(void* ptr)
|
||||
{
|
||||
return task_run_handle(detail::task_ptr(static_cast<detail::task_base*>(ptr)));
|
||||
}
|
||||
// Run the task and release the handle
|
||||
void run()
|
||||
{
|
||||
handle->vtable->run(handle.get());
|
||||
handle = nullptr;
|
||||
}
|
||||
|
||||
// Run the task but run the given wait handler when waiting for a task,
|
||||
// instead of just sleeping.
|
||||
void run_with_wait_handler(wait_handler handler)
|
||||
{
|
||||
wait_handler old = set_thread_wait_handler(handler);
|
||||
run();
|
||||
set_thread_wait_handler(old);
|
||||
}
|
||||
|
||||
// Conversion to and from void pointer. This allows the task handle to be
|
||||
// sent through C APIs which don't preserve types.
|
||||
void *to_void_ptr() { return handle.release(); }
|
||||
|
||||
static task_run_handle from_void_ptr(void *ptr)
|
||||
{
|
||||
return task_run_handle(detail::task_ptr(static_cast<detail::task_base *>(ptr)));
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
// Schedule a task for execution using its scheduler
|
||||
template<typename Sched>
|
||||
void schedule_task(Sched& sched, task_ptr t)
|
||||
void
|
||||
schedule_task(Sched &sched, task_ptr t)
|
||||
{
|
||||
static_assert(is_scheduler<Sched>::value, "Type is not a valid scheduler");
|
||||
sched.schedule(task_run_handle(std::move(t)));
|
||||
static_assert(is_scheduler<Sched>::value, "Type is not a valid scheduler");
|
||||
sched.schedule(task_run_handle(std::move(t)));
|
||||
}
|
||||
|
||||
// Inline scheduler implementation
|
||||
inline void inline_scheduler_impl::schedule(task_run_handle t)
|
||||
inline void
|
||||
inline_scheduler_impl::schedule(task_run_handle t)
|
||||
{
|
||||
t.run();
|
||||
t.run();
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
} // namespace async
|
||||
}// namespace detail
|
||||
}// namespace async
|
||||
|
@ -63,10 +63,15 @@ typedef ref_count_ptr<task_base> task_ptr;
|
||||
template<typename Sched>
|
||||
void schedule_task(Sched &sched, task_ptr t);
|
||||
|
||||
void generic_wait_for_task(task_base *wait_task);
|
||||
// Wait for the given task to finish. This will call the wait handler currently
|
||||
// active for this thread, which causes the thread to sleep by default.
|
||||
#ifndef LIBASYNC_CUSTOM_WAIT_FOR_TASK
|
||||
LIBASYNC_EXPORT void wait_for_task(task_base *wait_task);
|
||||
inline void
|
||||
wait_for_task(task_base *wait_task)
|
||||
{
|
||||
generic_wait_for_task(wait_task);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Forward-declaration for data used by threadpool_scheduler
|
||||
|
Reference in New Issue
Block a user