浏览代码

* Implemented basic task

master
bergmann 4 年前
父节点
当前提交
6dd9b9f724
共有 4 个文件被更改,包括 189 次插入0 次删除
  1. +2
    -0
      include/asyncpp/core.h
  2. +73
    -0
      include/asyncpp/core/task.h
  3. +66
    -0
      include/asyncpp/core/task.inl
  4. +48
    -0
      test/asyncpp/core/task_tests.cpp

+ 2
- 0
include/asyncpp/core.h 查看文件

@@ -3,7 +3,9 @@
#include "core/future.h"
#include "core/result.h"
#include "core/stream.h"
#include "core/task.h"

#include "core/future.inl"
#include "core/result.inl"
#include "core/stream.inl"
#include "core/task.inl"

+ 73
- 0
include/asyncpp/core/task.h 查看文件

@@ -0,0 +1,73 @@
#pragma once

#include <memory>

namespace asyncpp
{

struct task
{
public:
/**
* @brief Destructor.
*/
virtual ~task() = default;

/**
* @brief Poll the future stored in the task.
*
* @return TRUE if the task is finished, FALSE otherwise.
*/
bool poll();

private:
/**
* @brief Actual implementation of the poll function.
*/
virtual bool poll_impl() = 0;

private:
struct storage
{
task* current { nullptr };
};

/**
* @brief Get the thread local storage.
*/
static inline storage& local_storage();
};

template<typename T_future>
struct task_tpl
: public task
{
public:
using future_type = T_future;

private:
future_type _future;

public:
/**
* @brief Constructor.
*/
template<typename X_future>
inline task_tpl(X_future&& p_future);

private:
/**
* @brief Actual implementation of the poll function.
*/
inline bool poll_impl() override;
};

using task_ptr_s = std::shared_ptr<task>;

/**
* @brief Create a task from the passed future.
*/
template<typename X_future>
inline task_ptr_s make_task(X_future&& p_future);

}

+ 66
- 0
include/asyncpp/core/task.inl 查看文件

@@ -0,0 +1,66 @@
#pragma once

namespace asyncpp
{

namespace __impl
{

struct current_lock
{
task* owner;
task*& storage;

current_lock(
task* p_owner,
task*& p_storage)
: owner (p_owner)
, storage (p_storage)
{
if (storage)
throw std::runtime_error("Thread local task instance is already assigned!");
storage = owner;
}

~current_lock()
{ storage = nullptr; }
};

}

/* task */

bool task::poll()
{
__impl::current_lock l(this, local_storage().current);
return poll_impl();
}

task::storage& task::local_storage()
{
thread_local storage value;
return value;
}

/* task_tpl */

template<typename T_future>
template<typename X_future>
task_tpl<T_future>::task_tpl(X_future&& p_future)
: _future(std::forward<X_future>(p_future))
{ }

template<typename T_future>
bool task_tpl<T_future>::poll_impl()
{ return _future.poll().is_ready(); }

/* misc */

template<typename X_future>
task_ptr_s make_task(X_future&& p_future)
{
using task_type = task_tpl<X_future>;
return std::make_shared<task_type>(std::forward<X_future>(p_future));
}

}

+ 48
- 0
test/asyncpp/core/task_tests.cpp 查看文件

@@ -0,0 +1,48 @@
#include <gtest/gtest.h>

#include <asyncpp.h>

using namespace ::testing;
using namespace ::asyncpp;

struct delay
{
int const delay { 5 };
int count { 0 };
};

namespace asyncpp
{

template<>
struct future_trait<delay, void>
: public future_base<future<delay, void>>
{
using value_type = int&;

template<typename T_future>
static inline auto poll(T_future& self)
{
using result_type = future_result<value_type>;

if (self.ref.count >= self.ref.delay)
return result_type::ready(self.ref.count);

++self.ref.count;
return result_type::not_ready();
}
};

}

TEST(task_tests, poll)
{
auto t = make_task(as_future(delay { 5, 0 }));

ASSERT_FALSE(t->poll());
ASSERT_FALSE(t->poll());
ASSERT_FALSE(t->poll());
ASSERT_FALSE(t->poll());
ASSERT_FALSE(t->poll());
ASSERT_TRUE (t->poll());
}

正在加载...
取消
保存