OR-Tools  9.6
concurrent_calls_guard.h
Go to the documentation of this file.
1 // Copyright 2010-2022 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 #ifndef OR_TOOLS_MATH_OPT_CORE_CONCURRENT_CALLS_GUARD_H_
15 #define OR_TOOLS_MATH_OPT_CORE_CONCURRENT_CALLS_GUARD_H_
16 
17 #include <utility>
18 
19 #include "absl/base/thread_annotations.h"
20 #include "absl/status/statusor.h"
21 #include "absl/synchronization/mutex.h"
22 
24 
25 // RAII class that is used to return an error when concurrent calls to some
26 // functions are made.
27 //
28 // Usage:
29 //
30 // // Calling f() and/or g() concurrently will return an error.
31 // class A {
32 // public:
33 // absl::StatusOr<...> f() {
34 // ASSIGN_OR_RETURN(const auto guard,
35 // ConcurrentCallsGuard::TryAcquire(tracker_));
36 // ...
37 // }
38 //
39 // absl::StatusOr<...> g() {
40 // ASSIGN_OR_RETURN(const auto guard,
41 // ConcurrentCallsGuard::TryAcquire(tracker_));
42 // ...
43 // }
44 //
45 // private:
46 // ConcurrentCallsGuard::Tracker tracker_;
47 // };
48 //
50  public:
51  // Tracker for pending calls.
52  class Tracker {
53  public:
54  Tracker() = default;
55 
56  Tracker(const Tracker&) = delete;
57  Tracker& operator=(const Tracker&) = delete;
58 
59  private:
60  friend class ConcurrentCallsGuard;
61 
62  absl::Mutex mutex_;
63  bool in_a_call_ ABSL_GUARDED_BY(mutex_) = false;
64  };
65 
66  // Returns an errors status when concurrent calls are made, or a guard that
67  // must only be kept on stack during the execution of the call.
68  static absl::StatusOr<ConcurrentCallsGuard> TryAcquire(Tracker& tracker);
69 
73 
75  : tracker_(std::exchange(other.tracker_, nullptr)) {}
76 
77  // Release the guard.
79 
80  private:
81  // Asserts that the mutex is held by the current thread.
82  explicit ConcurrentCallsGuard(Tracker* const tracker) : tracker_(tracker) {}
83 
84  // Reset to nullptr when the class is moved by the move constructor.
85  Tracker* tracker_;
86 };
87 
88 } // namespace operations_research::math_opt
89 
90 #endif // OR_TOOLS_MATH_OPT_CORE_CONCURRENT_CALLS_GUARD_H_
ConcurrentCallsGuard & operator=(ConcurrentCallsGuard &&)=delete
ConcurrentCallsGuard & operator=(const ConcurrentCallsGuard &)=delete
static absl::StatusOr< ConcurrentCallsGuard > TryAcquire(Tracker &tracker)
ConcurrentCallsGuard(const ConcurrentCallsGuard &)=delete