X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=blobdiff_plain;f=folly%2Fio%2Fasync%2FEventBase.cpp;h=a4cbfa2055724c6c94166ffa98f4db3f2e6734db;hp=2474a0e8cdd91840dba2c3a2aa93a9450bead423;hb=ad0f7b2703ffc886a13ec5b420a5282cda380ae1;hpb=4c7d52264b25ade4758be7631aca68721a2704d5 diff --git a/folly/io/async/EventBase.cpp b/folly/io/async/EventBase.cpp index 2474a0e8..a4cbfa20 100644 --- a/folly/io/async/EventBase.cpp +++ b/folly/io/async/EventBase.cpp @@ -89,6 +89,28 @@ class EventBase::FunctionRunner } }; +/* + * EventBase::CobTimeout methods + */ + +void EventBase::CobTimeout::timeoutExpired() noexcept { + // For now, we just swallow any exceptions that the callback threw. + try { + cob_(); + } catch (const std::exception& ex) { + LOG(ERROR) << "EventBase::runAfterDelay() callback threw " + << typeid(ex).name() << " exception: " << ex.what(); + } catch (...) { + LOG(ERROR) << "EventBase::runAfterDelay() callback threw non-exception " + << "type"; + } + + // The CobTimeout object was allocated on the heap by runAfterDelay(), + // so delete it now that the it has fired. + delete this; +} + + // The interface used to libevent is not thread-safe. Calls to // event_init() and event_base_free() directly modify an internal // global 'current_base', so a mutex is required to protect this. @@ -188,7 +210,14 @@ EventBase::~EventBase() { callback->runLoopCallback(); } - clearCobTimeouts(); + // Delete any unfired callback objects, so that we don't leak memory + // (Note that we don't fire them. The caller is responsible for cleaning up + // its own data structures if it destroys the EventBase with unfired events + // remaining.) + while (!pendingCobTimeouts_.empty()) { + CobTimeout* timeout = &pendingCobTimeouts_.front(); + delete timeout; + } while (!runBeforeLoopCallbacks_.empty()) { delete &runBeforeLoopCallbacks_.front(); @@ -591,6 +620,29 @@ bool EventBase::runImmediatelyOrRunInEventBaseThreadAndWait(Func fn) { } } +void EventBase::runAfterDelay( + Func cob, + uint32_t milliseconds, + TimeoutManager::InternalEnum in) { + if (!tryRunAfterDelay(std::move(cob), milliseconds, in)) { + folly::throwSystemError( + "error in EventBase::runAfterDelay(), failed to schedule timeout"); + } +} + +bool EventBase::tryRunAfterDelay( + Func cob, + uint32_t milliseconds, + TimeoutManager::InternalEnum in) { + CobTimeout* timeout = new CobTimeout(this, std::move(cob), in); + if (!timeout->scheduleTimeout(milliseconds)) { + delete timeout; + return false; + } + pendingCobTimeouts_.push_back(*timeout); + return true; +} + bool EventBase::runLoopCallbacks() { if (!loopCallbacks_.empty()) { bumpHandlingTime();