xref: /aosp_15_r20/external/federated-compute/fcp/secagg/shared/async_abort.h (revision 14675a029014e728ec732f129a32e299b2da0601)
1 /*
2  * Copyright 2020 Google LLC
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     https://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef FCP_SECAGG_SHARED_ASYNC_ABORT_H_
18 #define FCP_SECAGG_SHARED_ASYNC_ABORT_H_
19 
20 #include <atomic>
21 #include <string>
22 
23 #include "absl/base/attributes.h"
24 #include "absl/synchronization/mutex.h"
25 #include "fcp/base/monitoring.h"
26 
27 namespace fcp {
28 namespace secagg {
29 
30 // A helper to allow polling for asynchronous aborts.  For ease of testing, this
31 // class does not manage its own atomic, which allows the atomic to be easily
32 // allocated on its own page.
33 //
34 // This class is thread-safe.
35 class AsyncAbort {
36  public:
AsyncAbort(std::atomic<std::string * > * signal)37   explicit AsyncAbort(std::atomic<std::string*>* signal)
38       : signal_(signal), mu_() {
39     FCP_CHECK(signal_);
40   }
41   virtual ~AsyncAbort() = default;
42 
43   // AsyncAbort is neither copyable nor movable.
44   AsyncAbort(const AsyncAbort&) = delete;
45   AsyncAbort& operator=(const AsyncAbort&) = delete;
46 
47   // Signal an async. abort.  The abort message may not be reflected in
48   // SecAggClient if it has already transitioned to a terminal state (aborted
49   // or completed).
Abort(std::string message)50   void Abort(std::string message) {
51     absl::WriterMutexLock _(&mu_);
52     message_ = message;
53     *signal_ = &message_;
54   }
55 
56   // Returns whether the abort signal is raised.
Signalled()57   ABSL_MUST_USE_RESULT bool Signalled() const {
58     return signal_->load(std::memory_order_relaxed);
59   }
60 
61   // Returns the abort message specified by the abort signal.
62   // If Signalled() returns false, the value is undefined.
Message()63   ABSL_MUST_USE_RESULT std::string Message() const {
64     absl::ReaderMutexLock _(&mu_);
65     return **signal_;
66   }
67 
68   std::atomic<std::string*>* signal_;
69   mutable absl::Mutex mu_;
70   std::string message_ ABSL_GUARDED_BY(mu_);
71 };
72 
73 }  // namespace secagg
74 }  // namespace fcp
75 
76 #endif  // FCP_SECAGG_SHARED_ASYNC_ABORT_H_
77