Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/mozglue/baseprofiler/public/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 10 kB image not shown  

Quelle  FailureLatch.h   Sprache: C

 
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


// This header contains an interface `FailureLatch`, and some implementation
// helpers that may be used across a range of classes and functions to handle
// failures at any point during a process, and share that failure state so that
// the process may gracefully stop quickly and report the first error.
//
// It could be thought as a replacement for C++ exceptions, but it's less strong
// (cancellations may be delayed).
// Now, if possible, mozilla::Result may be a better option as C++ exceptions
// replacement, as it is more visible in all affected functions.
// Consider FailureLatch if failures may happen in different places, but where
// `return`ing this potential failure from all functions would be too arduous.

#ifndef mozilla_FailureLatch_h
#define mozilla_FailureLatch_h

#include <mozilla/Assertions.h>

#include <string>

namespace mozilla {

// ----------------------------------------------------------------------------
// Main interface
// ----------------------------------------------------------------------------

// Interface handling a failure latch (starting in a successful state, the first
// failure gets recorded, subsequent failures are ignored.)
class FailureLatch {
 public:
  virtual ~FailureLatch() = default;

  // Can this ever fail? (This may influence how some code deals with
  // failures, e.g., if infallible, OOMs should assert&crash.)
  [[nodiscard]] virtual bool Fallible() const = 0;

  // Set latch in its failed state because of an external cause.
  // The first call sets the reason, subsequent calls are ignored.
  virtual void SetFailure(std::string aReason) = 0;

  // Has there been any failure so far?
  [[nodiscard]] virtual bool Failed() const = 0;

  // Return first failure string, may be null if not failed yet.
  [[nodiscard]] virtual const char* GetFailure() const = 0;

  // Retrieve the one source FailureLatch. It could reference `*this`!
  // This may be used by dependent proxy FailureLatch'es to find where to
  // redirect calls.
  [[nodiscard]] virtual const FailureLatch& SourceFailureLatch() const = 0;
  [[nodiscard]] virtual FailureLatch& SourceFailureLatch() = 0;

  // Non-virtual helpers.

  // Transfer any failure from another FailureLatch.
  void SetFailureFrom(const FailureLatch& aOther) {
    if (Failed()) {
      return;
    }
    if (const char* otherFailure = aOther.GetFailure(); otherFailure) {
      SetFailure(otherFailure);
    }
  }
};

// ----------------------------------------------------------------------------
// Concrete implementations
// ----------------------------------------------------------------------------

// Concrete infallible FailureLatch class.
// Any `SetFailure` leads to an assert-crash, so the final runtime result can
// always be assumed to be succesful.
class FailureLatchInfallibleSource final : public FailureLatch {
 public:
  [[nodiscard]] bool Fallible() const final { return false; }

  void SetFailure(std::string aReason) final {
    MOZ_RELEASE_ASSERT(false,
                       "SetFailure in infallible FailureLatchInfallibleSource");
  }

  [[nodiscard]] bool Failed() const final { return false; }

  [[nodiscard]] const char* GetFailure() const final { return nullptr; }

  [[nodiscard]] const ::mozilla::FailureLatch& SourceFailureLatch()
      const final {
    return *this;
  }

  [[nodiscard]] ::mozilla::FailureLatch& SourceFailureLatch() final {
    return *this;
  }

  // Singleton FailureLatchInfallibleSource that may be used as default
  // FailureLatch proxy.
  static FailureLatchInfallibleSource& Singleton() {
    static FailureLatchInfallibleSource singleton;
    return singleton;
  }
};

// Concrete FailureLatch class, intended to be intantiated as an object shared
// between classes and functions that are part of a long operation, so that
// failures can happen anywhere and be visible everywhere.
// Not thread-safe.
class FailureLatchSource final : public FailureLatch {
 public:
  [[nodiscard]] bool Fallible() const final { return true; }

  void SetFailure(std::string aReason) final {
    if (!mFailed) {
      mFailed = true;
      mReason = std::move(aReason);
    }
  }

  [[nodiscard]] bool Failed() const final { return mFailed; }

  [[nodiscard]] const char* GetFailure() const final {
    return mFailed ? mReason.c_str() : nullptr;
  }

  [[nodiscard]] const FailureLatch& SourceFailureLatch() const final {
    return *this;
  }

  [[nodiscard]] FailureLatch& SourceFailureLatch() final { return *this; }

 private:
  bool mFailed = false;
  std::string mReason;
};

// ----------------------------------------------------------------------------
// Helper macros, to be used in FailureLatch-derived classes
// ----------------------------------------------------------------------------

// Classes deriving from FailureLatch can use this to forward virtual calls to
// another FailureLatch.
#define FAILURELATCH_IMPL_PROXY(FAILURELATCH_REF)                        \
  [[nodiscard]] bool Fallible() const final {                            \
    return static_cast<const ::mozilla::FailureLatch&>(FAILURELATCH_REF) \
        .Fallible();                                                     \
  }                                                                      \
  void SetFailure(std::string aReason) final {                           \
    static_cast<::mozilla::FailureLatch&>(FAILURELATCH_REF)              \
        .SetFailure(std::move(aReason));                                 \
  }                                                                      \
  [[nodiscard]] bool Failed() const final {                              \
    return static_cast<const ::mozilla::FailureLatch&>(FAILURELATCH_REF) \
        .Failed();                                                       \
  }                                                                      \
  [[nodiscard]] const char* GetFailure() const final {                   \
    return static_cast<const ::mozilla::FailureLatch&>(FAILURELATCH_REF) \
        .GetFailure();                                                   \
  }                                                                      \
  [[nodiscard]] const FailureLatch& SourceFailureLatch() const final {   \
    return static_cast<const ::mozilla::FailureLatch&>(FAILURELATCH_REF) \
        .SourceFailureLatch();                                           \
  }                                                                      \
  [[nodiscard]] FailureLatch& SourceFailureLatch() final {               \
    return static_cast<::mozilla::FailureLatch&>(FAILURELATCH_REF)       \
        .SourceFailureLatch();                                           \
  }

// Classes deriving from FailureLatch can use this to forward virtual calls to
// another FailureLatch through a pointer, unless it's null in which case act
// like an infallible FailureLatch.
#define FAILURELATCH_IMPL_PROXY_OR_INFALLIBLE(FAILURELATCH_PTR, CLASS_NAME)    \
  [[nodiscard]] bool Fallible() const final {                                  \
    return FAILURELATCH_PTR                                                    \
               ? static_cast<const ::mozilla::FailureLatch*>(FAILURELATCH_PTR) \
                     ->Fallible()                                              \
               : false;                                                        \
  }                                                                            \
  void SetFailure(std::string aReason) final {                                 \
    if (FAILURELATCH_PTR) {                                                    \
      static_cast<::mozilla::FailureLatch*>(FAILURELATCH_PTR)                  \
          ->SetFailure(std::move(aReason));                                    \
    } else {                                                                   \
      MOZ_RELEASE_ASSERT(false"SetFailure in infallible " #CLASS_NAME);      \
    }                                                                          \
  }                                                                            \
  [[nodiscard]] bool Failed() const final {                                    \
    return FAILURELATCH_PTR                                                    \
               ? static_cast<const ::mozilla::FailureLatch*>(FAILURELATCH_PTR) \
                     ->Failed()                                                \
               : false;                                                        \
  }                                                                            \
  [[nodiscard]] const char* GetFailure() const final {                         \
    return FAILURELATCH_PTR                                                    \
               ? static_cast<const ::mozilla::FailureLatch*>(FAILURELATCH_PTR) \
                     ->GetFailure()                                            \
               : nullptr;                                                      \
  }                                                                            \
  [[nodiscard]] const FailureLatch& SourceFailureLatch() const final {         \
    return FAILURELATCH_PTR                                                    \
               ? static_cast<const ::mozilla::FailureLatch*>(FAILURELATCH_PTR) \
                     ->SourceFailureLatch()                                    \
               : ::mozilla::FailureLatchInfallibleSource::Singleton();         \
  }                                                                            \
  [[nodiscard]] FailureLatch& SourceFailureLatch() final {                     \
    return FAILURELATCH_PTR                                                    \
               ? static_cast<::mozilla::FailureLatch*>(FAILURELATCH_PTR)       \
                     ->SourceFailureLatch()                                    \
               : ::mozilla::FailureLatchInfallibleSource::Singleton();         \
  }

}  // namespace mozilla

#endif /* mozilla_FailureLatch_h */

Messung V0.5
C=95 H=91 G=92

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.