xref: /aosp_15_r20/external/zstd/contrib/pzstd/ErrorHolder.h (revision 01826a4963a0d8a59bc3812d29bdf0fb76416722)
1*01826a49SYabin Cui /*
2*01826a49SYabin Cui  * Copyright (c) Meta Platforms, Inc. and affiliates.
3*01826a49SYabin Cui  * All rights reserved.
4*01826a49SYabin Cui  *
5*01826a49SYabin Cui  * This source code is licensed under both the BSD-style license (found in the
6*01826a49SYabin Cui  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7*01826a49SYabin Cui  * in the COPYING file in the root directory of this source tree).
8*01826a49SYabin Cui  */
9*01826a49SYabin Cui #pragma once
10*01826a49SYabin Cui 
11*01826a49SYabin Cui #include <atomic>
12*01826a49SYabin Cui #include <cassert>
13*01826a49SYabin Cui #include <stdexcept>
14*01826a49SYabin Cui #include <string>
15*01826a49SYabin Cui 
16*01826a49SYabin Cui namespace pzstd {
17*01826a49SYabin Cui 
18*01826a49SYabin Cui // Coordinates graceful shutdown of the pzstd pipeline
19*01826a49SYabin Cui class ErrorHolder {
20*01826a49SYabin Cui   std::atomic<bool> error_;
21*01826a49SYabin Cui   std::string message_;
22*01826a49SYabin Cui 
23*01826a49SYabin Cui  public:
ErrorHolder()24*01826a49SYabin Cui   ErrorHolder() : error_(false) {}
25*01826a49SYabin Cui 
hasError()26*01826a49SYabin Cui   bool hasError() noexcept {
27*01826a49SYabin Cui     return error_.load();
28*01826a49SYabin Cui   }
29*01826a49SYabin Cui 
setError(std::string message)30*01826a49SYabin Cui   void setError(std::string message) noexcept {
31*01826a49SYabin Cui     // Given multiple possibly concurrent calls, exactly one will ever succeed.
32*01826a49SYabin Cui     bool expected = false;
33*01826a49SYabin Cui     if (error_.compare_exchange_strong(expected, true)) {
34*01826a49SYabin Cui       message_ = std::move(message);
35*01826a49SYabin Cui     }
36*01826a49SYabin Cui   }
37*01826a49SYabin Cui 
check(bool predicate,std::string message)38*01826a49SYabin Cui   bool check(bool predicate, std::string message) noexcept {
39*01826a49SYabin Cui     if (!predicate) {
40*01826a49SYabin Cui       setError(std::move(message));
41*01826a49SYabin Cui     }
42*01826a49SYabin Cui     return !hasError();
43*01826a49SYabin Cui   }
44*01826a49SYabin Cui 
getError()45*01826a49SYabin Cui   std::string getError() noexcept {
46*01826a49SYabin Cui     error_.store(false);
47*01826a49SYabin Cui     return std::move(message_);
48*01826a49SYabin Cui   }
49*01826a49SYabin Cui 
~ErrorHolder()50*01826a49SYabin Cui   ~ErrorHolder() {
51*01826a49SYabin Cui     assert(!hasError());
52*01826a49SYabin Cui   }
53*01826a49SYabin Cui };
54*01826a49SYabin Cui }
55