YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/util/ev_util.h
Line
Count
Source (jump to first uncovered line)
1
//
2
// Copyright (c) YugaByte, Inc.
3
//
4
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5
// in compliance with the License.  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 distributed under the License
10
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11
// or implied.  See the License for the specific language governing permissions and limitations
12
// under the License.
13
//
14
//
15
16
#ifndef YB_UTIL_EV_UTIL_H
17
#define YB_UTIL_EV_UTIL_H
18
19
#include <ev++.h>
20
21
#include "yb/util/atomic.h"
22
#include "yb/util/monotime.h"
23
24
namespace yb {
25
26
// We need to do all operations with ev::timer from the same thread, but for example RPC connection
27
// could be held by shared_ptr inside RPC calls even after reactor is shutdown. Connection
28
// destructor could be invoked from another thread after shutdown.
29
// EvTimerHolder provides a shutdown function to destroy embedded timer, so it won't be destroyed
30
// on holder destruction.
31
// This class is not thread-safe, but allowed to be destructed from any thread given that it was
32
// previously shutdown from owning thread.
33
class EvTimerHolder {
34
 public:
35
1.88M
  EvTimerHolder() {}
36
37
1.23M
  ~EvTimerHolder() {
38
1.23M
    auto* timer = timer_.get();
39
18.4E
    LOG_IF(DFATAL, timer) << "Timer " << timer << " should be already shutdown " << this;
40
1.23M
  }
41
42
  // Should be called before first usage of timer.
43
  void Init(const ev::loop_ref& loop);
44
45
  // Should be invoked from the timer loop thread before holder destruction.
46
  // Safe to call multiple times.
47
  void Shutdown();
48
49
114M
  bool IsInitialized() {
50
114M
    return timer_.get();
51
114M
  }
52
53
  // Starts timer after `left` time period.
54
113M
  void Start(CoarseMonoClock::Duration left) {
55
113M
    GetInitialized()->start(MonoDelta(left).ToSeconds(), 0 /* repeat */);
56
113M
  }
57
58
  // Sets method of the `object` as a callback for timer.
59
  template<class T, void (T::*Method)(ev::timer &w, int)> // NOLINT
60
1.54M
  void SetCallback(T* object) {
61
1.54M
    GetInitialized()->set<T, Method>(object);
62
1.54M
  }
_ZN2yb13EvTimerHolder11SetCallbackINS_3rpc10ConnectionEXadL_ZNS3_13HandleTimeoutERN2ev5timerEiEEEEvPT_
Line
Count
Source
60
940k
  void SetCallback(T* object) {
61
940k
    GetInitialized()->set<T, Method>(object);
62
940k
  }
_ZN2yb13EvTimerHolder11SetCallbackINS_3rpc26YBInboundConnectionContextEXadL_ZNS3_13HandleTimeoutERN2ev5timerEiEEEEvPT_
Line
Count
Source
60
304k
  void SetCallback(T* object) {
61
304k
    GetInitialized()->set<T, Method>(object);
62
304k
  }
_ZN2yb13EvTimerHolder11SetCallbackINS_3rpc27YBOutboundConnectionContextEXadL_ZNS3_13HandleTimeoutERN2ev5timerEiEEEEvPT_
Line
Count
Source
60
298k
  void SetCallback(T* object) {
61
298k
    GetInitialized()->set<T, Method>(object);
62
298k
  }
63
64
0
  ev::timer& operator*() {
65
0
    return *GetInitialized();
66
0
  }
67
68
0
  ev::timer* operator->() {
69
0
    return GetInitialized();
70
0
  }
71
72
 private:
73
114M
  ev::timer* GetInitialized() {
74
4.03k
    LOG_IF(DFATAL, !IsInitialized()) << "Timer should be previously initialized";
75
114M
    return timer_.get();
76
114M
  }
77
78
  AtomicUniquePtr<ev::timer> timer_;
79
};
80
81
} // namespace yb
82
83
#endif // YB_UTIL_EV_UTIL_H