VirtualEventBase.cpp 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /*
  2. * Copyright 2016-present Facebook, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <folly/io/async/VirtualEventBase.h>
  17. namespace folly {
  18. VirtualEventBase::VirtualEventBase(EventBase& evb)
  19. : evb_(getKeepAliveToken(evb)) {}
  20. std::future<void> VirtualEventBase::destroy() {
  21. CHECK(evb_->runInEventBaseThread([this] { loopKeepAlive_.reset(); }));
  22. return std::move(destroyFuture_);
  23. }
  24. void VirtualEventBase::destroyImpl() {
  25. try {
  26. {
  27. // After destroyPromise_ is posted this object may be destroyed, so make
  28. // sure we release EventBase's keep-alive token before that.
  29. SCOPE_EXIT {
  30. evb_.reset();
  31. };
  32. clearCobTimeouts();
  33. // To avoid potential deadlock, do not hold the mutex while invoking
  34. // user-supplied callbacks.
  35. LoopCallbackList callbacks;
  36. onDestructionCallbacks_.swap(callbacks);
  37. while (!callbacks.empty()) {
  38. auto& callback = callbacks.front();
  39. callbacks.pop_front();
  40. callback.runLoopCallback();
  41. }
  42. }
  43. destroyPromise_.set_value();
  44. } catch (...) {
  45. destroyPromise_.set_exception(std::current_exception());
  46. }
  47. }
  48. VirtualEventBase::~VirtualEventBase() {
  49. if (!destroyFuture_.valid()) {
  50. return;
  51. }
  52. CHECK(!evb_->inRunningEventBaseThread());
  53. destroy().get();
  54. }
  55. void VirtualEventBase::runOnDestruction(EventBase::LoopCallback* callback) {
  56. onDestructionCallbacks_.withWLock([&](LoopCallbackList& callbacks) {
  57. callback->cancelLoopCallback();
  58. callbacks.push_back(*callback);
  59. });
  60. }
  61. } // namespace folly