2 * Copyright 2004-present Facebook, Inc.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include <boost/noncopyable.hpp>
22 #include <glog/logging.h>
24 #include <folly/io/async/EventUtil.h>
25 #include <folly/portability/Event.h>
32 * The EventHandler class is used to asynchronously wait for events on a file
35 * Users that wish to wait on I/O events should derive from EventHandler and
36 * implement the handlerReady() method.
38 class EventHandler : private boost::noncopyable {
44 READ_WRITE = (READ | WRITE),
46 // Temporary flag until EPOLLPRI is upstream on libevent.
53 * Create a new EventHandler object.
55 * @param eventBase The EventBase to use to drive this event handler.
56 * This may be nullptr, in which case the EventBase must be
57 * set separately using initHandler() or attachEventBase()
58 * before the handler can be registered.
59 * @param fd The file descriptor that this EventHandler will
60 * monitor. This may be -1, in which case the file
61 * descriptor must be set separately using initHandler() or
62 * changeHandlerFD() before the handler can be registered.
64 explicit EventHandler(EventBase* eventBase = nullptr, int fd = -1);
67 * EventHandler destructor.
69 * The event will be automatically unregistered if it is still registered.
71 virtual ~EventHandler();
74 * handlerReady() is invoked when the handler is ready.
76 * @param events A bitset indicating the events that are ready.
78 virtual void handlerReady(uint16_t events) noexcept = 0;
81 * Register the handler.
83 * If the handler is already registered, the registration will be updated
84 * to wait on the new set of events.
86 * @param events A bitset specifying the events to monitor.
87 * If the PERSIST bit is set, the handler will remain
88 * registered even after handlerReady() is called.
90 * @return Returns true if the handler was successfully registered,
91 * or false if an error occurred. After an error, the handler is
92 * always unregistered, even if it was already registered prior to
93 * this call to registerHandler().
95 bool registerHandler(uint16_t events) {
96 return registerImpl(events, false);
100 * Unregister the handler, if it is registered.
102 void unregisterHandler();
105 * Returns true if the handler is currently registered.
107 bool isHandlerRegistered() const {
108 return EventUtil::isEventRegistered(&event_);
112 * Attach the handler to a EventBase.
114 * This may only be called if the handler is not currently attached to a
115 * EventBase (either by using the default constructor, or by calling
116 * detachEventBase()).
118 * This method must be invoked in the EventBase's thread.
120 void attachEventBase(EventBase* eventBase);
123 * Detach the handler from its EventBase.
125 * This may only be called when the handler is not currently registered.
126 * Once detached, the handler may not be registered again until it is
127 * re-attached to a EventBase by calling attachEventBase().
129 * This method must be called from the current EventBase's thread.
131 void detachEventBase();
134 * Change the file descriptor that this handler is associated with.
136 * This may only be called when the handler is not currently registered.
138 void changeHandlerFD(int fd);
141 * Attach the handler to a EventBase, and change the file descriptor.
143 * This method may only be called if the handler is not currently attached to
144 * a EventBase. This is primarily intended to be used to initialize
145 * EventHandler objects created using the default constructor.
147 void initHandler(EventBase* eventBase, int fd);
150 * Return the set of events that we're currently registered for.
152 uint16_t getRegisteredEvents() const {
153 return (isHandlerRegistered()) ? uint16_t(event_.ev_events) : 0u;
157 * Register the handler as an internal event.
159 * This event will not count as an active event for determining if the
160 * EventBase loop has more events to process. The EventBase loop runs
161 * only as long as there are active EventHandlers, however "internal" event
162 * handlers are not counted. Therefore this event handler will not prevent
163 * EventBase loop from exiting with no more work to do if there are no other
164 * non-internal event handlers registered.
166 * This is intended to be used only in very rare cases by the internal
167 * EventBase code. This API is not guaranteed to remain stable or portable
170 bool registerInternalHandler(uint16_t events) {
171 return registerImpl(events, true);
174 bool isPending() const;
177 bool registerImpl(uint16_t events, bool internal);
178 void ensureNotRegistered(const char* fn);
180 void setEventBase(EventBase* eventBase);
182 static void libeventCallback(libevent_fd_t fd, short events, void* arg);
185 EventBase* eventBase_;