Sort #include lines
[folly.git] / folly / io / async / EventHandler.h
1 /*
2  * Copyright 2004-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
17 #pragma once
18
19 #include <cstddef>
20
21 #include <boost/noncopyable.hpp>
22 #include <glog/logging.h>
23
24 #include <folly/io/async/EventUtil.h>
25 #include <folly/portability/Event.h>
26
27 namespace folly {
28
29 class EventBase;
30
31 /**
32  * The EventHandler class is used to asynchronously wait for events on a file
33  * descriptor.
34  *
35  * Users that wish to wait on I/O events should derive from EventHandler and
36  * implement the handlerReady() method.
37  */
38 class EventHandler : private boost::noncopyable {
39  public:
40   enum EventFlags {
41     NONE = 0,
42     READ = EV_READ,
43     WRITE = EV_WRITE,
44     READ_WRITE = (READ | WRITE),
45     PERSIST = EV_PERSIST,
46 // Temporary flag until EPOLLPRI is upstream on libevent.
47 #ifdef EV_PRI
48     PRI = EV_PRI,
49 #endif
50   };
51
52   /**
53    * Create a new EventHandler object.
54    *
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.
63    */
64   explicit EventHandler(EventBase* eventBase = nullptr, int fd = -1);
65
66   /**
67    * EventHandler destructor.
68    *
69    * The event will be automatically unregistered if it is still registered.
70    */
71   virtual ~EventHandler();
72
73   /**
74    * handlerReady() is invoked when the handler is ready.
75    *
76    * @param events  A bitset indicating the events that are ready.
77    */
78   virtual void handlerReady(uint16_t events) noexcept = 0;
79
80   /**
81    * Register the handler.
82    *
83    * If the handler is already registered, the registration will be updated
84    * to wait on the new set of events.
85    *
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.
89    *
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().
94    */
95   bool registerHandler(uint16_t events) {
96     return registerImpl(events, false);
97   }
98
99   /**
100    * Unregister the handler, if it is registered.
101    */
102   void unregisterHandler();
103
104   /**
105    * Returns true if the handler is currently registered.
106    */
107   bool isHandlerRegistered() const {
108     return EventUtil::isEventRegistered(&event_);
109   }
110
111   /**
112    * Attach the handler to a EventBase.
113    *
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()).
117    *
118    * This method must be invoked in the EventBase's thread.
119    */
120   void attachEventBase(EventBase* eventBase);
121
122   /**
123    * Detach the handler from its EventBase.
124    *
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().
128    *
129    * This method must be called from the current EventBase's thread.
130    */
131   void detachEventBase();
132
133   /**
134    * Change the file descriptor that this handler is associated with.
135    *
136    * This may only be called when the handler is not currently registered.
137    */
138   void changeHandlerFD(int fd);
139
140   /**
141    * Attach the handler to a EventBase, and change the file descriptor.
142    *
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.
146    */
147   void initHandler(EventBase* eventBase, int fd);
148
149   /**
150    * Return the set of events that we're currently registered for.
151    */
152   uint16_t getRegisteredEvents() const {
153     return (isHandlerRegistered()) ? uint16_t(event_.ev_events) : 0u;
154   }
155
156   /**
157    * Register the handler as an internal event.
158    *
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.
165    *
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
168    * in the future.
169    */
170   bool registerInternalHandler(uint16_t events) {
171     return registerImpl(events, true);
172   }
173
174   bool isPending() const;
175
176  private:
177   bool registerImpl(uint16_t events, bool internal);
178   void ensureNotRegistered(const char* fn);
179
180   void setEventBase(EventBase* eventBase);
181
182   static void libeventCallback(libevent_fd_t fd, short events, void* arg);
183
184   struct event event_;
185   EventBase* eventBase_;
186 };
187
188 } // folly