Use a base hook rather than a member hook for EventBase callbacks
authorChristopher Dykes <cdykes@fb.com>
Tue, 16 Aug 2016 22:44:03 +0000 (15:44 -0700)
committerFacebook Github Bot 8 <facebook-github-bot-8-bot@fb.com>
Tue, 16 Aug 2016 22:53:29 +0000 (15:53 -0700)
Summary:
Using boost intrusive member hooks in complex inheritence heirarchies under MSVC is [unsupported](http://www.boost.org/doc/libs/1_61_0/doc/html/intrusive/usage.html#intrusive.usage.usage_member_hook), and, in combination with a [regression in VS 2015 Update 2](https://connect.microsoft.com/VisualStudio/Feedback/Details/2555433) that is not fixed in Update 3, the async socket tests that use this compile under MSVC, but fail at runtime because the hook pointer ends up pointing at the node's vtable rather than the hook.
This just works around the issue by using a base hook instead.

Reviewed By: djwatson

Differential Revision: D3724521

fbshipit-source-id: a55e36a2e79a15d9943b6090f6194fd480e19074

folly/io/async/EventBase.h

index 6a508129915e08223bfa1b05956a3bf1b2b0205f..7f8aaeb8862c91bb4b396d57b561244bcac51299 100644 (file)
@@ -136,29 +136,24 @@ class EventBase : private boost::noncopyable,
    * If a LoopCallback object is destroyed while it is scheduled to be run in
    * the next loop iteration, it will automatically be cancelled.
    */
-  class LoopCallback {
+  class LoopCallback
+      : public boost::intrusive::list_base_hook<
+            boost::intrusive::link_mode<boost::intrusive::auto_unlink>> {
    public:
     virtual ~LoopCallback() = default;
 
     virtual void runLoopCallback() noexcept = 0;
     void cancelLoopCallback() {
-      hook_.unlink();
+      unlink();
     }
 
     bool isLoopCallbackScheduled() const {
-      return hook_.is_linked();
+      return is_linked();
     }
 
    private:
-    typedef boost::intrusive::list_member_hook<
-      boost::intrusive::link_mode<boost::intrusive::auto_unlink> > ListHook;
-
-    ListHook hook_;
-
     typedef boost::intrusive::list<
       LoopCallback,
-      boost::intrusive::member_hook<LoopCallback, ListHook,
-                                    &LoopCallback::hook_>,
       boost::intrusive::constant_time_size<false> > List;
 
     // EventBase needs access to LoopCallbackList (and therefore to hook_)