Skip to content

Commit

Permalink
删除 executor_awaitable
Browse files Browse the repository at this point in the history
由于 callback_awaitable 已经具备了自动兼容 executor 的机制。因此额外提供
executor_awaitable 的意义没有了。删掉 executor_awaitable 之。

另外,更新之前写 callback_awaitable 的时候还强制依赖 executor_awaitable
的 test 代码。
  • Loading branch information
microcai authored and EvinceMoi committed Oct 17, 2024
1 parent a44f0fa commit d5c819b
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 69 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,12 @@ awaitable<void> some_work_with_sleep()
}
```

async_qtimer_shot 只要使用 executor_awaitable 对 QTimer::singleShot 进行一次小小的封装就可以了。
async_qtimer_shot 只要使用 callback_awaitable 对 QTimer::singleShot 进行一次小小的封装就可以了。

```cpp
awaitable<void> async_qtimer_shot(int ms)
{
co_await executor_awaitable<void>([ms](auto continuation) {
co_await callback_awaitable<void>([ms](auto continuation) {
QTimer::singleShot(ms, [continuation = std::move(continuation)]() mutable
{
continuation();
Expand All @@ -141,7 +141,7 @@ awaitable<void> async_qtimer_shot(int ms)
可见这种封装是非常容易的。
如果需要 处理有返回值的回调,则只需要把 executor_awaitable<void> 里的 void 替换为相应的类型即可。
如果需要 处理有返回值的回调,则只需要把 `callback_awaitable<void>` 里的 void 替换为相应的类型即可。
例如为 QTcpSocket 封装为异步读取:
Expand All @@ -150,7 +150,7 @@ awaitable<int> async_read_qsocket(QTcpSocket* s, void* buffer, int buffer_size)
{
QObject* context = new QObject{s};
auto read_size = co_await executor_awaitable<int>([&context, s, buffer, buffers_size](auto continuation)
auto read_size = co_await callback_awaitable<int>([&context, s, buffer, buffers_size](auto continuation)
{
QObject::connect(s, &QIODevice::readyRead, context,
[s, &context, buffer, buffers_size]() mutable
Expand Down
42 changes: 0 additions & 42 deletions include/ucoro/awaitable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -602,42 +602,6 @@ namespace ucoro
CallbackFunction callback_function_;
};

//////////////////////////////////////////////////////////////////////////

template<typename T, typename CallbackFunction>
struct ExecutorAwaiter : public CallbackAwaiterBase<T>
{
public:
explicit ExecutorAwaiter(CallbackFunction&& callback_function)
: callback_function_(std::move(callback_function))
{
}

constexpr bool await_ready() noexcept
{
return false;
}

void await_suspend(std::coroutine_handle<> handle)
{
if constexpr (std::is_void_v<T>)
{
callback_function_(handle);
}
else
{
callback_function_([handle = std::move(handle), this](T t) mutable
{
this->result_ = std::move(t);
handle.resume();
});
}
}

private:
CallbackFunction callback_function_;
};

} // namespace ucoro

//////////////////////////////////////////////////////////////////////////
Expand All @@ -648,12 +612,6 @@ ucoro::CallbackAwaiter<T, callback> callback_awaitable(callback&& cb)
return ucoro::CallbackAwaiter<T, callback>{std::forward<callback>(cb)};
}

template<typename T, typename callback>
ucoro::ExecutorAwaiter<T, callback> executor_awaitable(callback&& cb)
{
return ucoro::ExecutorAwaiter<T, callback>{std::forward<callback>(cb)};
}

template<typename Awaitable, typename Local>
auto coro_start(Awaitable&& coro, Local&& local)
{
Expand Down
6 changes: 0 additions & 6 deletions tests/test3/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,10 @@
int main(int argc, char **argv)
{
using CallbackAwaiterType0 = ucoro::CallbackAwaiter<void, decltype([](auto h) {}) >;
using ExecutorAwaiterType0 = ucoro::ExecutorAwaiter<void, decltype([](auto h) {}) > ;

using CallbackAwaiterType1 = ucoro::CallbackAwaiter<int, decltype([](auto h) {}) > ;
using ExecutorAwaiterType1 = ucoro::ExecutorAwaiter<int, decltype([](auto h) {}) > ;

static_assert(ucoro::detail::is_awaiter_v < CallbackAwaiterType0 >, "not a coroutine");
static_assert(ucoro::detail::is_awaiter_v < ExecutorAwaiterType0 >, "not a coroutine");

static_assert(ucoro::detail::is_awaiter_v < CallbackAwaiterType1 >, "not a coroutine");
static_assert(ucoro::detail::is_awaiter_v < ExecutorAwaiterType1 >, "not a coroutine");

static_assert(ucoro::detail::is_awaiter_v < ucoro::awaitable<void> >, "not a coroutine");
static_assert(ucoro::detail::is_awaiter_v < ucoro::awaitable<int> >, "not a coroutine");
Expand Down
61 changes: 49 additions & 12 deletions tests/test_curl/test_curl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,53 @@

#include "curl/curl.h"

struct completion_job_data
{
static void do_completion_job(void* completion_data)
{
(*reinterpret_cast<completion_job_data*>(completion_data))();
delete reinterpret_cast<completion_job_data*>(completion_data);
}

virtual ~completion_job_data()
{
}

virtual void operator() ()
{
}
};


template<typename continuation_t>
struct completion_job_data_for_coro : public completion_job_data
{
continuation_t continuation;

completion_job_data_for_coro(continuation_t&& continuation)
: continuation(continuation)
{
}

virtual void operator() () override
{
continuation();
}
};

ucoro::awaitable<void> async_curl_http_post(std::string url)
{
CURLM *curl = co_await ucoro::local_storage_t<CURLM *>{};
CURLM* curl = co_await ucoro::local_storage_t<CURLM*>{};

co_await executor_awaitable<void>([curl, url](std::coroutine_handle<void> continuation)
co_await callback_awaitable<void>([curl, url](auto continuation)
{
auto http_handle = curl_easy_init();

auto complete_op = new completion_job_data_for_coro<decltype(continuation)>(std::move(continuation));

/* set the options (I left out a few, you get the point anyway) */
curl_easy_setopt(http_handle, CURLOPT_URL, url.c_str());
curl_easy_setopt(http_handle, CURLOPT_PRIVATE, continuation.address());
curl_easy_setopt(http_handle, CURLOPT_PRIVATE, complete_op);
curl_multi_add_handle(curl, http_handle);
curl_multi_wakeup(curl);

Expand Down Expand Up @@ -57,7 +93,7 @@ ucoro::awaitable<void> coro_compute()
global_exit_loop = true;
}

int main(int argc, char **argv)
int main(int argc, char** argv)
{
curl_global_init(CURL_GLOBAL_ALL);
auto curl = curl_multi_init();
Expand All @@ -70,9 +106,9 @@ int main(int argc, char **argv)
// 注意这里,执行到这里的时候,上诉 NOTE 里的 2号位代码执行完毕,return 了。1号位的代码,尚未执行到。

int msgs_left = -1;
CURLMsg *msg;
CURLMsg* msg;

for(;;)
for (;;)
{
int still_alive = 1;
curl_multi_perform(curl, &still_alive);
Expand All @@ -82,14 +118,13 @@ int main(int argc, char **argv)
{
if (msg->msg == CURLMSG_DONE)
{
CURL *e = msg->easy_handle;
CURL* e = msg->easy_handle;
fprintf(stderr, "R: %d - %s\n", msg->data.result, curl_easy_strerror(msg->data.result));
void * coroutine_handle_address = nullptr;
curl_easy_getinfo(e, CURLINFO_PRIVATE, &coroutine_handle_address);
if (coroutine_handle_address)
void* completion_job_data = nullptr;
curl_easy_getinfo(e, CURLINFO_PRIVATE, &completion_job_data);
if (completion_job_data)
{
auto completion_handle = std::coroutine_handle<void>::from_address(coroutine_handle_address);
completion_handle();
completion_job_data::do_completion_job(completion_job_data);
}

curl_multi_remove_handle(curl, e);
Expand All @@ -102,7 +137,9 @@ int main(int argc, char **argv)
}

if (global_exit_loop)
{
break;
}

curl_multi_wait(curl, NULL, 0, 1000, NULL);
}
Expand Down
35 changes: 30 additions & 5 deletions tests/testlibevent/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,48 @@

#include "event2/event.h"

template<typename continuation_t>
struct completion_job_data_for_coro
{
continuation_t continuation_;

event * ev_;

completion_job_data_for_coro(continuation_t&& continuation)
: continuation_(continuation)
, ev_(nullptr)
{
}

void operator() ()
{
continuation_();
event_free(ev_);
}
};

ucoro::awaitable<void> async_sleep_with_event_timer(int ms)
{
event_base* io = co_await ucoro::local_storage_t<event_base*>();

co_await executor_awaitable<void>([ms, io](auto continuation)
co_await callback_awaitable<void>([ms, io](auto continuation)
{
timeval tout = {
.tv_sec = ms / 1000,
.tv_usec = 1000 * (ms % 1000)
};

auto ev = event_new(io, -1, 0, [](evutil_socket_t, short, void * continuation_address)
auto complete_op = new completion_job_data_for_coro<decltype(continuation)>(std::move(continuation));

auto ev = event_new(io, -1, 0, [](evutil_socket_t, short, void * user_data)
{
auto continuation_ = std::coroutine_handle<>::from_address(continuation_address);
continuation_.resume();
}, continuation.address());
auto complete_op = reinterpret_cast<completion_job_data_for_coro<decltype(continuation)>*>(user_data);
(*complete_op)();
delete complete_op;

}, complete_op);

complete_op->ev_ = ev;
event_add(ev, &tout);
});
}
Expand Down

0 comments on commit d5c819b

Please sign in to comment.