-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
原先为了避免协程循环导致的爆栈, callback_awaitable 实现成了两种。 一种是在非 executor 环境下调用 另一种是在 executor 环境下调用的 executor_awaitable 非 executor 环境下使用的 callback_awaitable 使用了新的 await_suspend 签名 通过直接返回 coroutine_handle 的方式避免对 .resume() 的直接调用 从而避免了爆栈问题 但是这也导致, callback_awaitable无法在 executor 环境下使用。 现在更新一下 callback_awaitable, 它可以自动判断出来 callback_awaitable 传给你 的 handle 有没有被投递给 executor。如果投递给了 executor 它就 让 await_suspend 返回 noop_coroutine, 等你调用 handle 的时候,它内部再调用对应协程的 resume 来恢 复协程。而如果你没有投递 handle, 而是在 callback_awaitable 传你 handle 的时候立 马调用, 则 await_suspend 就会通过向协程框架返回 协程句柄的方式避免嵌套resume导致的 爆栈。 下面简述原理: callback_awaitable 调用 用户的回调函数的时候,会传入一个 handle 用户通过调用这个 handle 实现 恢复协程。让 co_await callback_awaitable 得以返回。 实现原理就是检测 handle 被调用的时候,是否是在 callback_awaitable 回调用户的上下文里。 也就是说,如果调用栈是 callback_awaitable::await_suspend -> user_lambda -> handle 那么,在 handle 的处理代码里,就标记一下,而不调用 coro_handle 的 resume 于是,等 user_lambda返回的时候,callback_awaitable::await_suspend 的代码通过检查 标记,就可以知道 handle 是不是被直接调用了。如果是,就 返回coro_handle, 否则返回 noop_coroutine. 如果 handle 的处理代码发现自己的调用栈不是 callback_awaitable::await_suspend 过 来的,则不做这个标记。 检查的方式如下: 1. 如果它发现自己运行的线程甚至不是 callback_awaitable::await_suspend 所运行的线程,则必然不在 callback_awaitable::await_suspend 的上下文里。 2. 通过检查一个共享的变量判断自己是否在 callback_awaitable::await_suspend 里面。 为啥 1. 要单独提出来呢? 因为 方法 2. 里有个隐含的条件,就是 handle 的处理代码, 和 callback_awaitable::await_suspend 调用 user_lambda 后的后续代码,是串行执行的。 如果只依赖 2. 这个方法,则可能判断出错。
- Loading branch information
Showing
6 changed files
with
61 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters