• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef GRPC_SRC_CORE_EXT_FILTERS_CHANNEL_IDLE_IDLE_FILTER_STATE_H
16 #define GRPC_SRC_CORE_EXT_FILTERS_CHANNEL_IDLE_IDLE_FILTER_STATE_H
17 
18 #include <grpc/support/port_platform.h>
19 #include <stdint.h>
20 
21 #include <atomic>
22 
23 namespace grpc_core {
24 
25 // State machine for the idle filter.
26 // Keeps track of how many calls are in progress, whether there is a timer
27 // started, and whether we've seen calls since the previous timer fired.
28 class IdleFilterState {
29  public:
30   explicit IdleFilterState(bool start_timer);
31   ~IdleFilterState() = default;
32 
33   IdleFilterState(const IdleFilterState&) = delete;
34   IdleFilterState& operator=(const IdleFilterState&) = delete;
35 
36   // Increment the number of calls in progress.
37   void IncreaseCallCount();
38 
39   // Decrement the number of calls in progress.
40   // Return true if we reached idle with no timer started.
41   GRPC_MUST_USE_RESULT bool DecreaseCallCount();
42 
43   // Check if there's been any activity since the last timer check.
44   // If there was, reset the activity flag and return true to indicated that
45   // a new timer should be started.
46   // If there was not, reset the timer flag and return false - in this case
47   // we know that the channel is idle and has been for one full cycle.
48   GRPC_MUST_USE_RESULT bool CheckTimer();
49 
50  private:
51   // Bit in state_ indicating that the timer has been started.
52   static constexpr uintptr_t kTimerStarted = 1;
53   // Bit in state_ indicating that we've seen a call start or stop since the
54   // last timer.
55   static constexpr uintptr_t kCallsStartedSinceLastTimerCheck = 2;
56   // How much should we shift to get the number of calls in progress.
57   static constexpr uintptr_t kCallsInProgressShift = 2;
58   // How much to increment/decrement the state_ when a call is started/stopped.
59   // Ensures we don't clobber the preceding bits.
60   static constexpr uintptr_t kCallIncrement = uintptr_t{1}
61                                               << kCallsInProgressShift;
62   std::atomic<uintptr_t> state_;
63 };
64 
65 }  // namespace grpc_core
66 
67 #endif  // GRPC_SRC_CORE_EXT_FILTERS_CHANNEL_IDLE_IDLE_FILTER_STATE_H
68