co_http
co_http copied to clipboard
!ret.is_error(EAGAIN) 中 为什么需要调用return cb(ret);
function:async_accept
......
auto ret =
convert_error<int>(accept(m_fd, &addr.m_addr, &addr.m_addrlen));
if (!ret.is_error(EAGAIN)) {
stop.clear_stop_callback();
cb(ret);//Server不会报错 和 chat_Server会报错
//return cb(ret);//Server 和 chat_Server都不会报错
//return;//Server会报错 和 chat_Server会报错
}
这里为什么必须调用cb(ret) 且需要return? 有没有大佬能够帮忙解释一下发生了什么?
完整代码:
auto ret =
convert_error<int>(accept(m_fd, &addr.m_addr, &addr.m_addrlen));
if (!ret.is_error(EAGAIN)) {
stop.clear_stop_callback();
return cb(ret);
}
// 如果 accept 到请求了,请操作系统,调用,我这个回调
return _epoll_callback(
[this, &addr, cb = std::move(cb), stop]() mutable {
return async_accept(addr, std::move(cb), stop);
},
EPOLLIN | EPOLLERR | EPOLLET | EPOLLONESHOT, stop);
return cb(ret)等价于: cb(ret); return; 如果没有这个early-return,那么就会执行到后面的_epoll_callback了,就会继续等待accept就绪。 然而只有当返回错误为EAGAIN时,才代表是因为“没有就绪”导致错误。 如果是其他错误,则应该直接返回错误,而不是继续_epoll_callback注册回调继续等待就绪,否则会死循环。 所以,必须要有return; 那么,为什么还要cb(ret)?无论错误与否,都需要返回,你可能误解成只有成功才会返回了。 即使发生了错误(除了EAGAIN这个特殊错误外),一样需要告诉调用者设置的回调,通过传入负数的方式。 一些语言的async函数则是支持双回调,出错一个回调,正常成功一个回调,例如javascript的Promise,有callback和reject两个回调,正常业务逻辑在callback里处理即可。而我的co_http没有采用分离回调的设计(boost.asio也没有),需要回调函数cb里自己if判断一下ret是否出错。