【发布时间】:2013-12-21 09:10:42
【问题描述】:
我正在实现一个看起来像 HTTP 服务器的东西,设计是:对于已经建立的连接,我想将它重用于多个请求,所以当请求完成时,我开始另一个带有 async_read 的读取任务,并启动deadline_timer。如果 60 秒内没有输入,则会触发计时器并破坏连接。让我恼火的是,在调用连接的析构函数之前,我们设置为async_read的回调会被调用。
那么,我的问题是,有没有什么办法可以取消挂起的读取任务,即在不调用回调函数的情况下破坏连接?
如果上面的通用描述不清楚,详细的工作流程如下(代码附在底部):
-
cleanup()在请求完成时被调用; - 在
cleanup()中启动定时器和另一个阅读任务; - 如果超时,则调用
HandleTimeout(),并调用stop(); - 在
stop()中,做clean工作,之后连接实例会被销毁。
但是,在第4步之后,会调用callback()函数,该函数注册在AsyncRead()中,那么,有什么办法可以取消callback()的调用呢?
代码:
class Connection : public boost::enable_shared_from_this<Connection>,
private boost::noncopyable {
public:
typedef Connection this_type;
void cleanup() {
timer_.expires_from_now(boost::posix_time::seconds(kDefaultTimeout));
timer_.async_wait(boost::bind(&this_type::HandleTimeout,
shared_from_this(),
boost::asio::placeholders::error));
AsyncRead();
}
void AsyncRead() {
boost::asio::async_read(*socket_, in_, boost::asio::transfer_at_least(1),
boost::bind(&this_type::callback,
shared_from_this(),
boost::asio::placeholders::error));
}
void callback(const boost::system::error_code& e) {
// ...
}
void HandleTimeout(const boost::system::error_code& e) {
if(e == boost::asio::error::operation_aborted)
LDEBUG << "The timeout timer is cancelled.";
else if(e)
LERROR << "Error occurred with the timer, message: " << e.message();
else if(timer_.expires_at()
<= boost::asio::deadline_timer::traits_type::now()) {
LDEBUG << "Connection timed out, close it.";
stop();
}
}
virtual void stop() {
connected_ = false;
socket_->close();
connection_manager_.stop(shared_from_this());
}
private:
// ...
boost::asio::deadline_timer timer_;
};
【问题讨论】:
标签: c++ boost-asio