• Alan Frindell's avatar
    Relax HHWheelTimer::destroy assertion to accommodate SharedPtr · 5e5cf95a
    Alan Frindell authored
    Summary:
    HHWheelTimer's auto-pointers are kind of funny.  You can do something like this:
    
    ```
    HHWheelTimer::UniquePtr p = ...;
    // create a SharedPtr from UniquePtr
    HHWheelTimer::SharedPtr s(p);
    // create another SharedPtr from raw ptr
    HHWheelTimer::SharedPtr s(p.get());
    // No problem.
    
    If you do this:
    
    HHWheelTimer::SharedPtr p = ....;
    // this leaks
    ```
    
    Why?  Because SharedPtr is only have of std::shared_ptr.  It's the refcounting half.  But when the last SharedPtr goes out of scope, it **does not** invoke HHWheelTimer::destroy().
    
    So code like this is possible/expected:
    
    ```
    MySweetObj::MySweetObj(HHWheelTimer::SharedPtr s) {
      s_ = s;
      s_.scheduleTimeout(a, b);
    }
    
    {
      HHWheelTimer::UniquePtr p = ...;
    
      obj = MySweetObj(p)
    
      // But what if I decide to kill p:
      p.reset();
    }
    ```
    
    Since MySweetObj takes a SharedPtr and holds it, it can reasonbly expect that it can schedule timeouts on it, and the HHWheelTimer will not be deleted until it releases the SharedPtr.  This is true, but the above code would hit the assert that count_ == 0.
    
    Instead, relase the check that count_ == 0 only if there are no extra outstanding SharedPtrs.
    
    Reviewed By: viswanathgs, chadparry
    
    Differential Revision: D2908729
    
    fb-gh-sync-id: 9abd4a7d692fe952c5514dbb8d85dfbad95a3cac
    shipit-source-id: 9abd4a7d692fe952c5514dbb8d85dfbad95a3cac
    5e5cf95a
HHWheelTimer.h 9.92 KB