Codemod: use #include angle brackets in folly and thrift
[folly.git] / folly / io / async / AsyncTimeout.h
1 /*
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
9  *
10  *   http://www.apache.org/licenses/LICENSE-2.0
11  *
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
17  * under the License.
18  */
19 #pragma once
20
21 #include <folly/io/async/TimeoutManager.h>
22
23 #include <boost/noncopyable.hpp>
24 #include <event.h>
25 #include <memory>
26
27 namespace folly {
28
29 class EventBase;
30 class RequestContext;
31 class TimeoutManager;
32
33 /**
34  * AsyncTimeout is used to asynchronously wait for a timeout to occur.
35  */
36 class AsyncTimeout : private boost::noncopyable {
37  public:
38   typedef TimeoutManager::InternalEnum InternalEnum;
39
40   /**
41    * Create a new AsyncTimeout object, driven by the specified TimeoutManager.
42    */
43   explicit AsyncTimeout(TimeoutManager* timeoutManager);
44   explicit AsyncTimeout(EventBase* eventBase);
45
46   /**
47    * Create a new internal AsyncTimeout object.
48    *
49    * Internal timeouts are like regular timeouts, but will not stop the
50    * TimeoutManager loop from exiting if the only remaining events are internal
51    * timeouts.
52    *
53    * This is useful for implementing fallback timeouts to abort the
54    * TimeoutManager loop if the other events have not been processed within a
55    * specified time period: if the event loop takes too long the timeout will
56    * fire and can stop the event loop.  However, if all other events complete,
57    * the event loop will exit even though the internal timeout is still
58    * installed.
59    */
60   AsyncTimeout(TimeoutManager* timeoutManager, InternalEnum internal);
61   AsyncTimeout(EventBase* eventBase, InternalEnum internal);
62
63   /**
64    * Create a new AsyncTimeout object, not yet assigned to a TimeoutManager.
65    *
66    * attachEventBase() must be called prior to scheduling the timeout.
67    */
68   AsyncTimeout();
69
70   /**
71    * AsyncTimeout destructor.
72    *
73    * The timeout will be automatically cancelled if it is running.
74    */
75   virtual ~AsyncTimeout();
76
77   /**
78    * timeoutExpired() is invoked when the timeout period has expired.
79    */
80   virtual void timeoutExpired() noexcept = 0;
81
82   /**
83    * Schedule the timeout to fire in the specified number of milliseconds.
84    *
85    * After the specified number of milliseconds has elapsed, timeoutExpired()
86    * will be invoked by the TimeoutManager's main loop.
87    *
88    * If the timeout is already running, it will be rescheduled with the
89    * new timeout value.
90    *
91    * @param milliseconds  The timeout duration, in milliseconds.
92    *
93    * @return Returns true if the timeout was successfully scheduled,
94    *         and false if an error occurred.  After an error, the timeout is
95    *         always unscheduled, even if scheduleTimeout() was just
96    *         rescheduling an existing timeout.
97    */
98   bool scheduleTimeout(uint32_t milliseconds);
99   bool scheduleTimeout(std::chrono::milliseconds timeout);
100
101   /**
102    * Cancel the timeout, if it is running.
103    */
104   void cancelTimeout();
105
106   /**
107    * Returns true if the timeout is currently scheduled.
108    */
109   bool isScheduled() const;
110
111   /**
112    * Attach the timeout to a TimeoutManager.
113    *
114    * This may only be called if the timeout is not currently attached to a
115    * TimeoutManager (either by using the default constructor, or by calling
116    * detachTimeoutManager()).
117    *
118    * This method must be invoked in the TimeoutManager's thread.
119    *
120    * The internal parameter specifies if this timeout should be treated as an
121    * internal event.  TimeoutManager::loop() will return when there are no more
122    * non-internal events remaining.
123    */
124   void attachTimeoutManager(TimeoutManager* timeoutManager,
125                             InternalEnum internal = InternalEnum::NORMAL);
126   void attachEventBase(EventBase* eventBase,
127                        InternalEnum internal = InternalEnum::NORMAL);
128
129   /**
130    * Detach the timeout from its TimeoutManager.
131    *
132    * This may only be called when the timeout is not running.
133    * Once detached, the timeout may not be scheduled again until it is
134    * re-attached to a EventBase by calling attachEventBase().
135    *
136    * This method must be called from the current TimeoutManager's thread.
137    */
138   void detachTimeoutManager();
139   void detachEventBase();
140
141   /**
142    * Returns the internal handle to the event
143    */
144   struct event* getEvent() {
145     return &event_;
146   }
147
148  private:
149   static void libeventCallback(int fd, short events, void* arg);
150
151   struct event event_;
152
153   /*
154    * Store a pointer to the TimeoutManager.  We only use this
155    * for some assert() statements, to make sure that AsyncTimeout is always
156    * used from the correct thread.
157    */
158   TimeoutManager* timeoutManager_;
159
160   // Save the request context for when the timeout fires.
161   std::shared_ptr<RequestContext> context_;
162 };
163
164 } // folly