YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/util/async_util.h
Line
Count
Source (jump to first uncovered line)
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
//
18
// The following only applies to changes made to this file as part of YugaByte development.
19
//
20
// Portions Copyright (c) YugaByte, Inc.
21
//
22
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
23
// in compliance with the License.  You may obtain a copy of the License at
24
//
25
// http://www.apache.org/licenses/LICENSE-2.0
26
//
27
// Unless required by applicable law or agreed to in writing, software distributed under the License
28
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
29
// or implied.  See the License for the specific language governing permissions and limitations
30
// under the License.
31
//
32
// Utility functions which are handy when doing async/callback-based programming.
33
#ifndef YB_UTIL_ASYNC_UTIL_H
34
#define YB_UTIL_ASYNC_UTIL_H
35
36
#include <pthread.h>
37
38
#include <future>
39
40
#include <boost/function.hpp>
41
42
#include "yb/gutil/macros.h"
43
44
#include "yb/util/monotime.h"
45
#include "yb/util/status.h"
46
#include "yb/util/status_callback.h"
47
48
namespace yb {
49
50
typedef boost::function<void(const Status&)> StatusFunctor;
51
52
// Simple class which can be used to make async methods synchronous.
53
// For example:
54
//   Synchronizer s;
55
//   SomeAsyncMethod(s.callback());
56
//   CHECK_OK(s.Wait());
57
class Synchronizer {
58
 public:
59
  Synchronizer(const Synchronizer&) = delete;
60
  void operator=(const Synchronizer&) = delete;
61
62
1.86M
  Synchronizer() {}
63
  ~Synchronizer();
64
65
  void StatusCB(const Status& status);
66
67
  // Use this for synchronizers declared on the stack. The callback does not take a reference to
68
  // its synchronizer, so the returned callback _must_ go out of scope before its synchronizer.
69
  StatusCallback AsStatusCallback();
70
71
  // Same semantics as AsStatusCallback.
72
  StdStatusCallback AsStdStatusCallback();
73
74
  // This version of AsStatusCallback is for cases when the callback can outlive the synchronizer.
75
  // The callback holds a weak pointer to the synchronizer.
76
  static StatusCallback AsStatusCallback(const std::shared_ptr<Synchronizer>& synchronizer);
77
78
0
  StatusFunctor AsStatusFunctor() {
79
0
    return std::bind(&Synchronizer::StatusCB, this, std::placeholders::_1);
80
0
  }
81
82
1.85M
  CHECKED_STATUS Wait() {
83
1.85M
    return WaitUntil(std::chrono::steady_clock::time_point::max());
84
1.85M
  }
85
86
5.72k
  CHECKED_STATUS WaitFor(const MonoDelta& delta) {
87
5.72k
    return WaitUntil(std::chrono::steady_clock::now() + delta.ToSteadyDuration());
88
5.72k
  }
89
90
  CHECKED_STATUS WaitUntil(const std::chrono::steady_clock::time_point& time);
91
92
  void Reset();
93
94
 private:
95
96
  // Invoked in the destructor and in Reset() to make sure Wait() was invoked if it had to be.
97
  void EnsureWaitDone();
98
99
  std::mutex mutex_;
100
  std::condition_variable cond_;
101
  bool assigned_ = false;
102
103
  // If we've created a callback and given it out to an asynchronous operation, we must call Wait()
104
  // on the synchronizer before destroying it. Not doing any locking around this variable because
105
  // Wait() is supposed to be called on the same thread as AsStatusCallback(), or with adequate
106
  // synchronization after that. Most frequently Wait() is called right after creating the
107
  // synchronizer.
108
  bool must_wait_ = false;
109
110
  Status status_;
111
};
112
113
// Functor is any functor that accepts callback as only argument.
114
template <class Result, class Functor>
115
246k
std::future<Result> MakeFuture(const Functor& functor) {
116
246k
  auto promise = std::make_shared<std::promise<Result>>();
117
246k
  auto future = promise->get_future();
118
246k
  functor([promise](Result result) {
119
246k
    promise->set_value(std::move(result));
120
246k
  });
client.cc:_ZZN2yb10MakeFutureINS_6ResultINSt3__110shared_ptrIKNS_6client27VersionedTablePartitionListEEEEEZNS4_12_GLOBAL__N_121FetchPartitionsFutureEPNS4_8YBClientERKNS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEE3$_5EENS2_6futureIT_EERKT0_ENKUlS8_E_clES8_
Line
Count
Source
118
85.4k
  functor([promise](Result result) {
119
85.4k
    promise->set_value(std::move(result));
120
85.4k
  });
Unexecuted instantiation: client.cc:_ZZN2yb10MakeFutureINS_6ResultINSt3__16vectorI13scoped_refptrINS_6client8internal12RemoteTabletEENS2_9allocatorIS8_EEEEEEZNS5_8YBClient22LookupAllTabletsFutureERKNS2_10shared_ptrIKNS5_7YBTableEEENS2_6chrono10time_pointINS_15CoarseMonoClockENSK_8durationIxNS2_5ratioILl1ELl1000000000EEEEEEEE3$_4EENS2_6futureIT_EERKT0_ENKUlSC_E_clESC_
Unexecuted instantiation: meta_cache.cc:_ZZN2yb10MakeFutureINS_6ResultI13scoped_refptrINS_6client8internal12RemoteTabletEEEEZNS4_9MetaCache23LookupTabletByKeyFutureERKNSt3__110shared_ptrINS3_7YBTableEEERKNS9_12basic_stringIcNS9_11char_traitsIcEENS9_9allocatorIcEEEENS9_6chrono10time_pointINS_15CoarseMonoClockENSN_8durationIxNS9_5ratioILl1ELl1000000000EEEEEEEE3$_5EENS9_6futureIT_EERKT0_ENKUlS7_E_clES7_
transaction.cc:_ZZN2yb10MakeFutureINS_6StatusEZNS_6client13YBTransaction12CommitFutureENSt3__16chrono10time_pointINS_15CoarseMonoClockENS5_8durationIxNS4_5ratioILl1ELl1000000000EEEEEEENS_17StronglyTypedBoolINS2_12SealOnly_TagEEEE3$_0EENS4_6futureIT_EERKT0_ENKUlS1_E_clES1_
Line
Count
Source
118
78.6k
  functor([promise](Result result) {
119
78.6k
    promise->set_value(std::move(result));
120
78.6k
  });
transaction.cc:_ZZN2yb10MakeFutureINS_6ResultINS_22ChildTransactionDataPBEEEZNS_6client13YBTransaction18PrepareChildFutureENS_17StronglyTypedBoolINS4_23ForceConsistentRead_TagEEENSt3__16chrono10time_pointINS_15CoarseMonoClockENSA_8durationIxNS9_5ratioILl1ELl1000000000EEEEEEEE3$_1EENS9_6futureIT_EERKT0_ENKUlS3_E_clES3_
Line
Count
Source
118
82.4k
  functor([promise](Result result) {
119
82.4k
    promise->set_value(std::move(result));
120
82.4k
  });
121
246k
  return future;
122
246k
}
client.cc:_ZN2yb10MakeFutureINS_6ResultINSt3__110shared_ptrIKNS_6client27VersionedTablePartitionListEEEEEZNS4_12_GLOBAL__N_121FetchPartitionsFutureEPNS4_8YBClientERKNS2_12basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEE3$_5EENS2_6futureIT_EERKT0_
Line
Count
Source
115
85.4k
std::future<Result> MakeFuture(const Functor& functor) {
116
85.4k
  auto promise = std::make_shared<std::promise<Result>>();
117
85.4k
  auto future = promise->get_future();
118
85.4k
  functor([promise](Result result) {
119
85.4k
    promise->set_value(std::move(result));
120
85.4k
  });
121
85.4k
  return future;
122
85.4k
}
Unexecuted instantiation: client.cc:_ZN2yb10MakeFutureINS_6ResultINSt3__16vectorI13scoped_refptrINS_6client8internal12RemoteTabletEENS2_9allocatorIS8_EEEEEEZNS5_8YBClient22LookupAllTabletsFutureERKNS2_10shared_ptrIKNS5_7YBTableEEENS2_6chrono10time_pointINS_15CoarseMonoClockENSK_8durationIxNS2_5ratioILl1ELl1000000000EEEEEEEE3$_4EENS2_6futureIT_EERKT0_
Unexecuted instantiation: meta_cache.cc:_ZN2yb10MakeFutureINS_6ResultI13scoped_refptrINS_6client8internal12RemoteTabletEEEEZNS4_9MetaCache23LookupTabletByKeyFutureERKNSt3__110shared_ptrINS3_7YBTableEEERKNS9_12basic_stringIcNS9_11char_traitsIcEENS9_9allocatorIcEEEENS9_6chrono10time_pointINS_15CoarseMonoClockENSN_8durationIxNS9_5ratioILl1ELl1000000000EEEEEEEE3$_5EENS9_6futureIT_EERKT0_
transaction.cc:_ZN2yb10MakeFutureINS_6StatusEZNS_6client13YBTransaction12CommitFutureENSt3__16chrono10time_pointINS_15CoarseMonoClockENS5_8durationIxNS4_5ratioILl1ELl1000000000EEEEEEENS_17StronglyTypedBoolINS2_12SealOnly_TagEEEE3$_0EENS4_6futureIT_EERKT0_
Line
Count
Source
115
78.6k
std::future<Result> MakeFuture(const Functor& functor) {
116
78.6k
  auto promise = std::make_shared<std::promise<Result>>();
117
78.6k
  auto future = promise->get_future();
118
78.6k
  functor([promise](Result result) {
119
78.6k
    promise->set_value(std::move(result));
120
78.6k
  });
121
78.6k
  return future;
122
78.6k
}
transaction.cc:_ZN2yb10MakeFutureINS_6ResultINS_22ChildTransactionDataPBEEEZNS_6client13YBTransaction18PrepareChildFutureENS_17StronglyTypedBoolINS4_23ForceConsistentRead_TagEEENSt3__16chrono10time_pointINS_15CoarseMonoClockENSA_8durationIxNS9_5ratioILl1ELl1000000000EEEEEEEE3$_1EENS9_6futureIT_EERKT0_
Line
Count
Source
115
82.3k
std::future<Result> MakeFuture(const Functor& functor) {
116
82.3k
  auto promise = std::make_shared<std::promise<Result>>();
117
82.3k
  auto future = promise->get_future();
118
82.3k
  functor([promise](Result result) {
119
82.3k
    promise->set_value(std::move(result));
120
82.3k
  });
121
82.3k
  return future;
122
82.3k
}
123
124
template <class T>
125
0
bool IsReady(const std::shared_future<T>& f) {
126
0
  return f.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
127
0
}
Unexecuted instantiation: _ZN2yb7IsReadyINS_6ResultINS_19TransactionMetadataEEEEEbRKNSt3__113shared_futureIT_EE
Unexecuted instantiation: _ZN2yb7IsReadyINS_6client11FlushStatusEEEbRKNSt3__113shared_futureIT_EE
Unexecuted instantiation: _ZN2yb7IsReadyINS_6StatusEEEbRKNSt3__113shared_futureIT_EE
128
129
template <class T>
130
0
bool IsReady(const std::future<T>& f) {
131
0
  return f.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
132
0
}
Unexecuted instantiation: _ZN2yb7IsReadyINS_6client11FlushStatusEEEbRKNSt3__16futureIT_EE
Unexecuted instantiation: _ZN2yb7IsReadyINS_6StatusEEEbRKNSt3__16futureIT_EE
133
134
} // namespace yb
135
#endif /* YB_UTIL_ASYNC_UTIL_H */