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