2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
21 #include <glog/logging.h>
22 #include <folly/io/async/EventUtil.h>
23 #include <boost/noncopyable.hpp>
31 * The EventHandler class is used to asynchronously wait for events on a file
34 * Users that wish to wait on I/O events should derive from EventHandler and
35 * implement the handlerReady() method.
37 class EventHandler : private boost::noncopyable {
43 READ_WRITE = (READ | WRITE),
48 * Create a new EventHandler object.
50 * @param eventBase The EventBase to use to drive this event handler.
51 * This may be nullptr, in which case the EventBase must be
52 * set separately using initHandler() or attachEventBase()
53 * before the handler can be registered.
54 * @param fd The file descriptor that this EventHandler will
55 * monitor. This may be -1, in which case the file
56 * descriptor must be set separately using initHandler() or
57 * changeHandlerFD() before the handler can be registered.
59 explicit EventHandler(EventBase* eventBase = nullptr, int fd = -1);
62 * EventHandler destructor.
64 * The event will be automatically unregistered if it is still registered.
66 virtual ~EventHandler();
69 * handlerReady() is invoked when the handler is ready.
71 * @param events A bitset indicating the events that are ready.
73 virtual void handlerReady(uint16_t events) noexcept = 0;
76 * Register the handler.
78 * If the handler is already registered, the registration will be updated
79 * to wait on the new set of events.
81 * @param events A bitset specifying the events to monitor.
82 * If the PERSIST bit is set, the handler will remain
83 * registered even after handlerReady() is called.
85 * @return Returns true if the handler was successfully registered,
86 * or false if an error occurred. After an error, the handler is
87 * always unregistered, even if it was already registered prior to
88 * this call to registerHandler().
90 bool registerHandler(uint16_t events) {
91 return registerImpl(events, false);
95 * Unregister the handler, if it is registered.
97 void unregisterHandler();
100 * Returns true if the handler is currently registered.
102 bool isHandlerRegistered() const {
103 return EventUtil::isEventRegistered(&event_);
107 * Attach the handler to a EventBase.
109 * This may only be called if the handler is not currently attached to a
110 * EventBase (either by using the default constructor, or by calling
111 * detachEventBase()).
113 * This method must be invoked in the EventBase's thread.
115 void attachEventBase(EventBase* eventBase);
118 * Detach the handler from its EventBase.
120 * This may only be called when the handler is not currently registered.
121 * Once detached, the handler may not be registered again until it is
122 * re-attached to a EventBase by calling attachEventBase().
124 * This method must be called from the current EventBase's thread.
126 void detachEventBase();
129 * Change the file descriptor that this handler is associated with.
131 * This may only be called when the handler is not currently registered.
133 void changeHandlerFD(int fd);
136 * Attach the handler to a EventBase, and change the file descriptor.
138 * This method may only be called if the handler is not currently attached to
139 * a EventBase. This is primarily intended to be used to initialize
140 * EventHandler objects created using the default constructor.
142 void initHandler(EventBase* eventBase, int fd);
145 * Return the set of events that we're currently registered for.
147 uint16_t getRegisteredEvents() const {
148 return (isHandlerRegistered()) ?
149 event_.ev_events : 0;
153 * Register the handler as an internal event.
155 * This event will not count as an active event for determining if the
156 * EventBase loop has more events to process. The EventBase loop runs
157 * only as long as there are active EventHandlers, however "internal" event
158 * handlers are not counted. Therefore this event handler will not prevent
159 * EventBase loop from exiting with no more work to do if there are no other
160 * non-internal event handlers registered.
162 * This is intended to be used only in very rare cases by the internal
163 * EventBase code. This API is not guaranteed to remain stable or portable
166 bool registerInternalHandler(uint16_t events) {
167 return registerImpl(events, true);
170 bool isPending() const;
173 bool registerImpl(uint16_t events, bool internal);
174 void ensureNotRegistered(const char* fn);
176 void setEventBase(EventBase* eventBase);
178 static void libeventCallback(int fd, short events, void* arg);
181 EventBase* eventBase_;