LCOV - code coverage report
Current view: top level - source/extensions/common/async_files - async_file_action.h (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 0 19 0.0 %
Date: 2024-01-05 06:35:25 Functions: 0 16 0.0 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <atomic>
       4             : #include <functional>
       5             : 
       6             : #include "envoy/common/pure.h"
       7             : 
       8             : #include "source/common/common/assert.h"
       9             : 
      10             : namespace Envoy {
      11             : namespace Extensions {
      12             : namespace Common {
      13             : namespace AsyncFiles {
      14             : 
      15             : // A CancelFunction attempts to stop an action in flight.
      16             : // * If the action already occurred, the CancelFunction does nothing.
      17             : // * If the action is already calling the callback, CancelFunction blocks until the callback
      18             : //   completes.
      19             : // * If the action is already executing, CancelFunction causes the removal of any resource-consuming
      20             : //   return value (e.g. file handles), and prevents the callback.
      21             : // * If the action is still just queued, CancelFunction prevents its execution.
      22             : using CancelFunction = std::function<void()>;
      23             : 
      24             : // Actions to be passed to asyncFileManager->enqueue.
      25             : class AsyncFileAction {
      26             : public:
      27           0 :   virtual ~AsyncFileAction() = default;
      28             : 
      29             :   // Cancel the action, as much as possible.
      30             :   //
      31             :   // If the action has not been started, it will become a no-op.
      32             :   //
      33             :   // If the action has started, onCancelledBeforeCallback will be called,
      34             :   // and the callback will not.
      35             :   //
      36             :   // If the callback is already being called, cancel will block until the
      37             :   // callback has completed.
      38             :   //
      39             :   // If the action is already complete, cancel does nothing.
      40             :   void cancel();
      41             : 
      42             :   // Performs the action represented by this instance, and calls the callback
      43             :   // on completion or on error.
      44             :   virtual void execute() PURE;
      45             : 
      46             : protected:
      47             :   enum class State { Queued, Executing, InCallback, Done, Cancelled };
      48             :   std::atomic<State> state_{State::Queued};
      49             : };
      50             : 
      51             : // All concrete AsyncFileActions are a subclass of AsyncFileActionWithResult.
      52             : // The template allows for different on_complete callback signatures appropriate
      53             : // to each specific action.
      54             : //
      55             : // on_complete callbacks run in the AsyncFileManager's thread pool, and therefore:
      56             : // 1. Should avoid using variables that may be out of scope by the time the callback is called.
      57             : // 2. May need to lock-guard variables that can be changed in other threads.
      58             : // 3. Must not block significantly or do significant work - if anything time-consuming is required
      59             : // the result should be passed to another thread for handling.
      60             : template <typename T> class AsyncFileActionWithResult : public AsyncFileAction {
      61             : public:
      62             :   explicit AsyncFileActionWithResult(std::function<void(T)> on_complete)
      63           0 :       : on_complete_(on_complete) {}
      64             : 
      65           0 :   void execute() final {
      66           0 :     State expected = State::Queued;
      67           0 :     if (!state_.compare_exchange_strong(expected, State::Executing)) {
      68           0 :       ASSERT(expected == State::Cancelled);
      69           0 :       return;
      70           0 :     }
      71           0 :     expected = State::Executing;
      72           0 :     T result = executeImpl();
      73           0 :     if (!state_.compare_exchange_strong(expected, State::InCallback)) {
      74           0 :       ASSERT(expected == State::Cancelled);
      75           0 :       onCancelledBeforeCallback(std::move(result));
      76           0 :       return;
      77           0 :     }
      78           0 :     on_complete_(std::move(result));
      79           0 :     state_.store(State::Done);
      80           0 :   }
      81             : 
      82             : protected:
      83             :   // Performs any action to undo side-effects of the execution if the callback
      84             :   // has not yet been called (e.g. closing a file that was just opened).
      85             :   // Not necessary for things that don't make persistent resources,
      86             :   // e.g. cancelling a write does not have to undo the write.
      87           0 :   virtual void onCancelledBeforeCallback(T){};
      88             : 
      89             :   // Implementation of the actual action.
      90             :   virtual T executeImpl() PURE;
      91             : 
      92             : private:
      93             :   std::function<void(T)> on_complete_;
      94             : };
      95             : 
      96             : } // namespace AsyncFiles
      97             : } // namespace Common
      98             : } // namespace Extensions
      99             : } // namespace Envoy

Generated by: LCOV version 1.15