1 /* 2 * Copyright 2018 Google LLC 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef FCP_BASE_SCHEDULER_H_ 18 #define FCP_BASE_SCHEDULER_H_ 19 20 /** 21 * Overview 22 * ======== 23 * 24 * A simple implementation of a scheduler (thread pool). Allows to schedule 25 * tasks and futures. 26 */ 27 28 #include <functional> 29 #include <memory> 30 31 #include "fcp/base/monitoring.h" 32 #include "fcp/base/move_to_lambda.h" 33 34 namespace fcp { 35 36 /** 37 * A Worker allows to schedule tasks which are executed sequentially. 38 * Workers are created from a Scheduler. 39 * 40 * Lifetime and destruction: 41 * 42 * - The scheduler from which a worker is created must not be destructed 43 * before the worker. 44 * 45 * - The worker must not be destructed before all its tasks are finished. 46 */ 47 class Worker { 48 public: 49 virtual ~Worker() = default; 50 Worker() = default; 51 52 Worker(Worker const&) = delete; 53 Worker& operator=(Worker const&) = delete; 54 55 /** 56 * Schedules a task on this worker. Tasks are executed strictly sequentially 57 * in the order they are scheduled. 58 */ 59 virtual void Schedule(std::function<void()> task) = 0; 60 }; 61 62 /** 63 * A Scheduler which allows to schedule 'tasks'. 64 * 65 * Lifetime and destruction: 66 * 67 * - A Scheduler *must* be idle (no active or pending work) at destruction 68 * time. See WaitUntilIdle. 69 * 70 * - Implies: A Scheduler *must not* be destructed by one of its own tasks 71 * 72 * - Implies: Task closures may safely hold raw pointers to their thread pool. 73 * They should *not* have ownership (via a smart-pointer or similar). 74 */ 75 class Scheduler { 76 public: 77 virtual ~Scheduler() = default; 78 Scheduler() = default; 79 80 Scheduler(Scheduler const&) = delete; 81 Scheduler& operator=(Scheduler const&) = delete; 82 83 /** 84 * Creates a new Worker based on this scheduler. 85 */ 86 virtual std::unique_ptr<Worker> CreateWorker(); 87 88 /** 89 * Schedules a task that will execute on the scheduler. 90 */ 91 virtual void Schedule(std::function<void()> task) = 0; 92 93 /** 94 * Waits until there are no tasks running or pending. 95 * 96 * In this state, the thread pool will not restart working until some 97 * external entity is scheduling new tasks, as work caused by tasks spawning 98 * other tasks has ceased. 99 */ 100 virtual void WaitUntilIdle() = 0; 101 }; 102 103 /** 104 * Creates a scheduler using a fixed-size pool of threads to run tasks. 105 */ 106 std::unique_ptr<Scheduler> CreateThreadPoolScheduler(std::size_t thread_count); 107 108 } // namespace fcp 109 110 #endif // FCP_BASE_SCHEDULER_H_ 111