alibaba / async_simple

Simple, light-weight and easy-to-use asynchronous components
Apache License 2.0
1.69k stars 251 forks source link

Introduce get_return_object_on_allocation_failure to Lazy (#338) #340

Closed ChuanqiXu9 closed 1 year ago

ChuanqiXu9 commented 1 year ago

This patch tries to introduce get_return_object_on_allocation_failure() to the promise_type of Lazy.

Why do we want to introduce get_return_object_on_allocation_failure()? Since a coroutine will be roughly converted to:

void *frame_addr = ::operator new(required size);
__promise_ = new (frame_addr) __promise_type(...);
__return_object_ = __promise_.get_return_object();
co_await __promise_.initial_suspend();
try {
    function-body
} catch (...) {
    __promise_.unhandled_exception();
}
co_await __promise_.final_suspend();

Then we can find that the coroutine should be nounwind (noexcept) naturally if the constructor of the promise_type, the get_return_object() function, the initial_suspend, the unhandled_exception(), the final_suspend and the allocation function is noexcept.

For the specific coroutine type, Lazy, all the above except the allocation function is noexcept. So that we can make every Lazy function noexcept naturally if we make the allocation function nothrow. This is the reason why we want to introduce get_return_object_on_allocation_failure() to Lazy.

Note that the optimization may not work in some platforms due the ABI limitations. Since they need to consider the case that the destructor of an exception can throw exceptions.

ChuanqiXu9 commented 1 year ago

这次用了更朴素的方式,内存分配失败就返回 Lazy(nullptr)。这样的话 handle 为 nullptr 对于 Lazy 的语义就是:

虽然有一些 hacky 但我不太想增加新的字段,这对性能会有影响,也会影响编译器优化

RainMark commented 1 year ago

这次用了更朴素的方式,内存分配失败就返回 Lazy(nullptr)。这样的话 handle 为 nullptr 对于 Lazy 的语义就是:

  • 没使用过:内存分配失败
  • 使用过

虽然有一些 hacky 但我不太想增加新的字段,这对性能会有影响,也会影响编译器优化

handle 是null行为是啥来着呢,什么也不会执行?然后外面怎么感知到了bad alloc了

ChuanqiXu9 commented 1 year ago

这次用了更朴素的方式,内存分配失败就返回 Lazy(nullptr)。这样的话 handle 为 nullptr 对于 Lazy 的语义就是:

  • 没使用过:内存分配失败
  • 使用过

虽然有一些 hacky 但我不太想增加新的字段,这对性能会有影响,也会影响编译器优化

handle 是null行为是啥来着呢,什么也不会执行?然后外面怎么感知到了bad alloc了

via 或者 co_await 的时候,会触发异常 std::logic_error,异常的 message 里写可能是内存分配失败或者使用了已使用过的 Lazy

RainMark commented 1 year ago

这次用了更朴素的方式,内存分配失败就返回 Lazy(nullptr)。这样的话 handle 为 nullptr 对于 Lazy 的语义就是:

  • 没使用过:内存分配失败
  • 使用过

虽然有一些 hacky 但我不太想增加新的字段,这对性能会有影响,也会影响编译器优化

handle 是null行为是啥来着呢,什么也不会执行?然后外面怎么感知到了bad alloc了

via 或者 co_await 的时候,会触发异常 std::logic_error,异常的 message 里写可能是内存分配失败或者使用了已使用过的 Lazy

嗯,好像暂时我也没想到啥好办法,要不先这样吧