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