简体   繁体   English

提高截止时间_计时器持有对对象的引用

[英]boost deadline_timer holds reference to object

I'm working with a boost deadline_timer which appears to be calling its handler after the owning object has been deleted. 我正在使用boost截止截止时间_timer,它似乎在删除拥有对象后正在调用其处理程序。 I've tried a couple of approaches to get this to work. 我尝试了几种方法来使它起作用。

First I just used the timer by binding to a handler and the owning object using 'shared_from_this' 首先,我通过使用“ shared_from_this”绑定到处理程序和拥有的对象来使用计时器

m_timer.expires_from_now(boost::posix_time::seconds(m_nHandshakeTimeout));
m_timer.async_wait(
    boost::bind(&CTcpSslSocket::handle_handshake_timeout, 
    shared_from_this(),
    boost::asio::placeholders::error)
    );

This method makes the timer function correctly but also causes a reference to the owning object to be held. 此方法可以使计时器正常工作,但也可以保留对拥有对象的引用。 I show that I've leaked the owning object when shutting down the application. 我显示关闭应用程序时泄漏了拥有的对象。 I ran into a similar issue a while ago which was resolved using a weak pointer (thanks to help from others here at stackoverflow). 不久前,我遇到了一个类似的问题,该问题使用弱指针解决(感谢stackoverflow上的其他人员的帮助)。 I tried the same thing with the timer by doing this: 我通过执行以下操作尝试了与计时器相同的操作:

m_timer.expires_from_now(boost::posix_time::seconds(m_nHandshakeTimeout));
boost::weak_ptr<CTcpSslSocket> weak( shared_from_this() );
m_timer.async_wait([=]( const boost::system::error_code& error ) {
    boost::shared_ptr<CTcpSslSocket> strong(weak);
    if ( strong ) {
        strong->handle_handshake_timeout(error);
    }
    return;
});

This also appears to work correctly as far as the timer functionality goes, but causes memory corruption when shutting down the application. 就计时器功能而言,这似乎也可以正常工作,但是在关闭应用程序时会导致内存损坏。 Running in the debugger shows that the exception occurs while boost code is calling the handler. 在调试器中运行表明,在Boost代码调用处理程序时会发生异常。

If the operation I use the timer for completes within the given time I cancel the timer, otherwise I don't do anything with the timer. 如果我使用计时器的操作在给定时间内完成,则取消计时器,否则我不对计时器执行任何操作。 Here's the cancel code: 这是取消代码:

if ( m_eHandshakeTimer != eExpired )
{
    m_eHandshakeTimer = eCanceled;
    m_timer.cancel();
}

Any ideas about how to solve this? 关于如何解决这个问题的任何想法?

Of course, holding a weak pointer does nothing to keep the object (CTcpSslSocket) alive. 当然,持有弱指针并不能使对象(CTcpSslSocket)保持活动状态。

A weak pointer is only able to observe the lifetime end of an object owned by a shared pointer. 弱指针只能观察共享指针拥有的对象的生存期。

Make the async operation share ownership instead. 改为使异步操作共享所有权。 This way, when you detect the timer has been canceled, then automatically you will free the shared object. 这样,当您检测到计时器已取消时,您将自动释放共享对象。

m_timer.expires_from_now(boost::posix_time::seconds(m_nHandshakeTimeout));
auto This = shared_from_this();
m_timer.async_wait([=]( const boost::system::error_code& error ) {
    if (ec != boost::asio::error::operation_aborted) {
        This->handle_handshake_timeout(error); 
           //  ^ could share This with other handlers to keep it alive
    }
    return;
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM