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