// Copyright 2019 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef UTIL_OPERATION_LOOP_H_ #define UTIL_OPERATION_LOOP_H_ #include #include #include #include #include "platform/api/time.h" #include "platform/base/macros.h" namespace openscreen { class OperationLoop { public: using OperationWithTimeout = std::function; // Creates a new OperationLoop from a variable number of operations. The // provided functions will be called repeatedly, at a minimum interval equal // to min_loop_execution_time, and are expected to exit after the time period // provided to their call has passed. This is because some operations may not // be safe to be interrupted from this class. // NOTE: If n operations are provided with operation timeout T, each iteration // of the operation loop may take as long as n * T, and will not exit after // min_loop_execution_time has elapsed. In order to avoid this behavior, the // caller can set min_loop_execution_time = n * T. // // operations = Functions to execute repeatedly. All functions are expected to // be valid the duration of this object's lifetime. // timeout = Timeout for each individual function above. // min_loop_execution_time = Minimum time that OperationLoop should wait // before successive calls to members of the // provided operations vector. OperationLoop(std::vector operations, Clock::duration timeout, Clock::duration min_loop_execution_time); // Runs the PerformAllOperations function in a loop until the below // RequestStopSoon function is called. void RunUntilStopped(); // Signals for the RunUntilStopped loop to cease running. void RequestStopSoon(); OSP_DISALLOW_COPY_AND_ASSIGN(OperationLoop); private: // Performs all operations which have been provided to this instance. void PerformAllOperations(); const Clock::duration perform_all_operations_min_execution_time_; const Clock::duration operation_timeout_; // Used to wait in PerformAllOperations() if not enough time has elapsed. std::condition_variable perform_all_operations_waiter_; // Mutex used by the above condition_variable. std::mutex wait_mutex_; // Represents whether this instance is currently "running". std::atomic_bool is_running_{false}; // Operations currently being run by this object. const std::vector operations_; }; } // namespace openscreen #endif // UTIL_OPERATION_LOOP_H_