Summary: Callbacks sometimes outlive the `HHWheelTimer` that they reference. Then the `Callback` tries to reference the dead `HHWheelTimer` and it could either misbehave or crash. This was caught reliably by ASAN tests.
Since `HHWheelTimer` already supports intrusive ref counting, the solution is to acquire a reference within the `Callback`.
Reviewed By: djwatson
Differential Revision:
D2617966
fb-gh-sync-id:
02be9ffc5851c269d5933288a17ad394b33ac2dd
#include <folly/io/async/HHWheelTimer.h>
#include <folly/io/async/Request.h>
+#include <folly/Optional.h>
#include <folly/ScopeGuard.h>
#include <cassert>
assert(wheel_ == nullptr);
assert(expiration_ == milliseconds(0));
+ wheelGuard_ = DestructorGuard(wheel);
wheel_ = wheel;
// Only update the now_ time if we're not in a timeout expired callback
hook_.unlink();
wheel_ = nullptr;
+ wheelGuard_ = folly::none;
expiration_ = milliseconds(0);
}
#pragma once
+#include <folly/Optional.h>
#include <folly/io/async/AsyncTimeout.h>
#include <folly/io/async/DelayedDestruction.h>
void cancelTimeoutImpl();
HHWheelTimer* wheel_;
+ folly::Optional<DestructorGuard> wheelGuard_;
std::chrono::milliseconds expiration_;
typedef boost::intrusive::list_member_hook<