EventHandler.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /*
  2. * Copyright 2014-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. #pragma once
  17. #include <cstddef>
  18. #include <boost/noncopyable.hpp>
  19. #include <glog/logging.h>
  20. #include <folly/io/async/EventUtil.h>
  21. #include <folly/portability/Event.h>
  22. namespace folly {
  23. class EventBase;
  24. /**
  25. * The EventHandler class is used to asynchronously wait for events on a file
  26. * descriptor.
  27. *
  28. * Users that wish to wait on I/O events should derive from EventHandler and
  29. * implement the handlerReady() method.
  30. */
  31. class EventHandler : private boost::noncopyable {
  32. public:
  33. enum EventFlags {
  34. NONE = 0,
  35. READ = EV_READ,
  36. WRITE = EV_WRITE,
  37. READ_WRITE = (READ | WRITE),
  38. PERSIST = EV_PERSIST,
  39. // Temporary flag until EPOLLPRI is upstream on libevent.
  40. #ifdef EV_PRI
  41. PRI = EV_PRI,
  42. #endif
  43. };
  44. /**
  45. * Create a new EventHandler object.
  46. *
  47. * @param eventBase The EventBase to use to drive this event handler.
  48. * This may be nullptr, in which case the EventBase must be
  49. * set separately using initHandler() or attachEventBase()
  50. * before the handler can be registered.
  51. * @param fd The file descriptor that this EventHandler will
  52. * monitor. This may be -1, in which case the file
  53. * descriptor must be set separately using initHandler() or
  54. * changeHandlerFD() before the handler can be registered.
  55. */
  56. explicit EventHandler(EventBase* eventBase = nullptr, int fd = -1);
  57. /**
  58. * EventHandler destructor.
  59. *
  60. * The event will be automatically unregistered if it is still registered.
  61. */
  62. virtual ~EventHandler();
  63. /**
  64. * handlerReady() is invoked when the handler is ready.
  65. *
  66. * @param events A bitset indicating the events that are ready.
  67. */
  68. virtual void handlerReady(uint16_t events) noexcept = 0;
  69. /**
  70. * Register the handler.
  71. *
  72. * If the handler is already registered, the registration will be updated
  73. * to wait on the new set of events.
  74. *
  75. * @param events A bitset specifying the events to monitor.
  76. * If the PERSIST bit is set, the handler will remain
  77. * registered even after handlerReady() is called.
  78. *
  79. * @return Returns true if the handler was successfully registered,
  80. * or false if an error occurred. After an error, the handler is
  81. * always unregistered, even if it was already registered prior to
  82. * this call to registerHandler().
  83. */
  84. bool registerHandler(uint16_t events) {
  85. return registerImpl(events, false);
  86. }
  87. /**
  88. * Unregister the handler, if it is registered.
  89. */
  90. void unregisterHandler();
  91. /**
  92. * Returns true if the handler is currently registered.
  93. */
  94. bool isHandlerRegistered() const {
  95. return EventUtil::isEventRegistered(&event_);
  96. }
  97. /**
  98. * Attach the handler to a EventBase.
  99. *
  100. * This may only be called if the handler is not currently attached to a
  101. * EventBase (either by using the default constructor, or by calling
  102. * detachEventBase()).
  103. *
  104. * This method must be invoked in the EventBase's thread.
  105. */
  106. void attachEventBase(EventBase* eventBase);
  107. /**
  108. * Detach the handler from its EventBase.
  109. *
  110. * This may only be called when the handler is not currently registered.
  111. * Once detached, the handler may not be registered again until it is
  112. * re-attached to a EventBase by calling attachEventBase().
  113. *
  114. * This method must be called from the current EventBase's thread.
  115. */
  116. void detachEventBase();
  117. /**
  118. * Change the file descriptor that this handler is associated with.
  119. *
  120. * This may only be called when the handler is not currently registered.
  121. */
  122. void changeHandlerFD(int fd);
  123. /**
  124. * Attach the handler to a EventBase, and change the file descriptor.
  125. *
  126. * This method may only be called if the handler is not currently attached to
  127. * a EventBase. This is primarily intended to be used to initialize
  128. * EventHandler objects created using the default constructor.
  129. */
  130. void initHandler(EventBase* eventBase, int fd);
  131. /**
  132. * Return the set of events that we're currently registered for.
  133. */
  134. uint16_t getRegisteredEvents() const {
  135. return (isHandlerRegistered()) ? uint16_t(event_.ev_events) : 0u;
  136. }
  137. /**
  138. * Register the handler as an internal event.
  139. *
  140. * This event will not count as an active event for determining if the
  141. * EventBase loop has more events to process. The EventBase loop runs
  142. * only as long as there are active EventHandlers, however "internal" event
  143. * handlers are not counted. Therefore this event handler will not prevent
  144. * EventBase loop from exiting with no more work to do if there are no other
  145. * non-internal event handlers registered.
  146. *
  147. * This is intended to be used only in very rare cases by the internal
  148. * EventBase code. This API is not guaranteed to remain stable or portable
  149. * in the future.
  150. */
  151. bool registerInternalHandler(uint16_t events) {
  152. return registerImpl(events, true);
  153. }
  154. bool isPending() const;
  155. private:
  156. bool registerImpl(uint16_t events, bool internal);
  157. void ensureNotRegistered(const char* fn);
  158. void setEventBase(EventBase* eventBase);
  159. static void libeventCallback(libevent_fd_t fd, short events, void* arg);
  160. struct event event_;
  161. EventBase* eventBase_;
  162. };
  163. } // namespace folly