2 * Copyright 2015 Facebook, Inc.
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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
23 #include <folly/io/async/TimeoutManager.h>
25 #include <boost/noncopyable.hpp>
36 * AsyncTimeout is used to asynchronously wait for a timeout to occur.
38 class AsyncTimeout : private boost::noncopyable {
40 typedef TimeoutManager::InternalEnum InternalEnum;
43 * Create a new AsyncTimeout object, driven by the specified TimeoutManager.
45 explicit AsyncTimeout(TimeoutManager* timeoutManager);
46 explicit AsyncTimeout(EventBase* eventBase);
49 * Create a new internal AsyncTimeout object.
51 * Internal timeouts are like regular timeouts, but will not stop the
52 * TimeoutManager loop from exiting if the only remaining events are internal
55 * This is useful for implementing fallback timeouts to abort the
56 * TimeoutManager loop if the other events have not been processed within a
57 * specified time period: if the event loop takes too long the timeout will
58 * fire and can stop the event loop. However, if all other events complete,
59 * the event loop will exit even though the internal timeout is still
62 AsyncTimeout(TimeoutManager* timeoutManager, InternalEnum internal);
63 AsyncTimeout(EventBase* eventBase, InternalEnum internal);
66 * Create a new AsyncTimeout object, not yet assigned to a TimeoutManager.
68 * attachEventBase() must be called prior to scheduling the timeout.
73 * AsyncTimeout destructor.
75 * The timeout will be automatically cancelled if it is running.
77 virtual ~AsyncTimeout();
80 * timeoutExpired() is invoked when the timeout period has expired.
82 virtual void timeoutExpired() noexcept = 0;
85 * Schedule the timeout to fire in the specified number of milliseconds.
87 * After the specified number of milliseconds has elapsed, timeoutExpired()
88 * will be invoked by the TimeoutManager's main loop.
90 * If the timeout is already running, it will be rescheduled with the
93 * @param milliseconds The timeout duration, in milliseconds.
95 * @return Returns true if the timeout was successfully scheduled,
96 * and false if an error occurred. After an error, the timeout is
97 * always unscheduled, even if scheduleTimeout() was just
98 * rescheduling an existing timeout.
100 bool scheduleTimeout(uint32_t milliseconds);
101 bool scheduleTimeout(std::chrono::milliseconds timeout);
104 * Cancel the timeout, if it is running.
106 void cancelTimeout();
109 * Returns true if the timeout is currently scheduled.
111 bool isScheduled() const;
114 * Attach the timeout to a TimeoutManager.
116 * This may only be called if the timeout is not currently attached to a
117 * TimeoutManager (either by using the default constructor, or by calling
118 * detachTimeoutManager()).
120 * This method must be invoked in the TimeoutManager's thread.
122 * The internal parameter specifies if this timeout should be treated as an
123 * internal event. TimeoutManager::loop() will return when there are no more
124 * non-internal events remaining.
126 void attachTimeoutManager(TimeoutManager* timeoutManager,
127 InternalEnum internal = InternalEnum::NORMAL);
128 void attachEventBase(EventBase* eventBase,
129 InternalEnum internal = InternalEnum::NORMAL);
132 * Detach the timeout from its TimeoutManager.
134 * This may only be called when the timeout is not running.
135 * Once detached, the timeout may not be scheduled again until it is
136 * re-attached to a EventBase by calling attachEventBase().
138 * This method must be called from the current TimeoutManager's thread.
140 void detachTimeoutManager();
141 void detachEventBase();
143 const TimeoutManager* getTimeoutManager() {
144 return timeoutManager_;
148 * Returns the internal handle to the event
150 struct event* getEvent() {
155 static void libeventCallback(int fd, short events, void* arg);
160 * Store a pointer to the TimeoutManager. We only use this
161 * for some assert() statements, to make sure that AsyncTimeout is always
162 * used from the correct thread.
164 TimeoutManager* timeoutManager_;
166 // Save the request context for when the timeout fires.
167 std::shared_ptr<RequestContext> context_;