aboutsummaryrefslogtreecommitdiff
path: root/util/operation_loop.h
diff options
context:
space:
mode:
Diffstat (limited to 'util/operation_loop.h')
-rw-r--r--util/operation_loop.h76
1 files changed, 76 insertions, 0 deletions
diff --git a/util/operation_loop.h b/util/operation_loop.h
new file mode 100644
index 00000000..155fe078
--- /dev/null
+++ b/util/operation_loop.h
@@ -0,0 +1,76 @@
+// 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 <atomic>
+#include <condition_variable>
+#include <functional>
+#include <vector>
+
+#include "platform/api/time.h"
+#include "platform/base/macros.h"
+
+namespace openscreen {
+
+using Clock = platform::Clock;
+
+class OperationLoop {
+ public:
+ using OperationWithTimeout = std::function<void(Clock::duration)>;
+
+ // 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<OperationWithTimeout> 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<OperationWithTimeout> operations_;
+};
+
+} // namespace openscreen
+
+#endif // UTIL_OPERATION_LOOP_H_