1 /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ 2 /* 3 * Copyright 2016 Couchbase, Inc. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 #pragma once 18 19 #include <condition_variable> 20 #include <deque> 21 #include <mutex> 22 #include <platform/platform.h> 23 24 class EngineManager; 25 26 /** 27 * The scrubber task is charged with 28 * 1. removing items from memory 29 * 2. deleting engine structs 30 * 31 * The common use-case is for bucket deletion performing tasks 1 and 2. 32 * The start_scrub command only performs 1. 33 * 34 * Global destruction can safely join the task and allow the engine to 35 * safely unload the shared object. 36 */ 37 class ScrubberTask { 38 public: 39 ScrubberTask(EngineManager& manager); 40 41 /** 42 * Shutdown the task 43 */ 44 void shutdown(); 45 46 /** 47 * Join the thread running the scrubber (to be called after shutdown). 48 */ 49 void joinThread(); 50 51 /** 52 * Place the engine on the threads work queue for item scrubbing. 53 * bool destroy indicates if the engine should be deleted once scrubbed. 54 */ 55 void placeOnWorkQueue(struct default_engine* engine, bool destroy); 56 57 /** 58 * Task's run loop method. This is not a public function and should only 59 * be called from the tasks constructor. 60 */ 61 void run(); 62 63 /** 64 * Is the scrubber idle and have no pending work scheduled 65 * 66 * @return true if no work has been scheduled and its work queue is empty 67 */ isIdle()68 bool isIdle() { 69 std::lock_guard<std::mutex> guard(lock); 70 return (workQueue.empty() && state == State::Idle); 71 } 72 73 private: 74 enum class State { 75 /// The scrubber is currently in the waiting state 76 Idle, 77 /// The scrubber is currently scrubbing a list 78 Scrubbing, 79 /// The scrubber task is stopped (returning from main) 80 Stopped 81 }; 82 83 /** What is the scrubber currently doing */ 84 State state; 85 86 /* 87 * A queue of engine's to work on. 88 * The second bool indicates if the engine is to be deleted when done. 89 */ 90 std::deque<std::pair<struct default_engine*, bool> > workQueue; 91 92 /** Is the task being requested to shut down? */ 93 bool shuttingdown; 94 95 /** The manager owning us */ 96 EngineManager& engineManager; 97 98 /** All internal state is protected by this mutex */ 99 std::mutex lock; 100 101 /** 102 * The condition variable used to notify the task that it has work 103 * to do. 104 */ 105 std::condition_variable cvar; 106 107 /** 108 * The identifier to the thread handle 109 */ 110 cb_thread_t scrubberThread; 111 }; 112