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 18/** 19 * Engine manager provides a C API for the managment of default_engine 20 * 'handles'. Creation / Deletion and the item scrubber thread are all 21 * managed by this module. 22 */ 23 24#ifdef __cplusplus 25#include <condition_variable> 26#include <mutex> 27#include <unordered_set> 28 29#include "scrubber_task.h" 30 31class EngineManager { 32public: 33 34 EngineManager(); 35 ~EngineManager(); 36 37 /** 38 * Create a new instance of the default_engine 39 * 40 * @return the newly created instance or nullptr if we ran out of 41 * resources (memory _or_ bucket id's) 42 */ 43 struct default_engine* createEngine(); 44 45 /** 46 * Request that the scrubber destroy's this engine. 47 * Scrubber will delete the object. 48 */ 49 void requestDestroyEngine(struct default_engine* engine); 50 51 /** 52 * Request that the engine is scrubbed. 53 */ 54 void scrubEngine(struct default_engine* engine); 55 56 /** 57 * Set the shutdown flag so that we can clean up 58 * 1) no new engine's can be created. 59 * 2) the scrubber can be notified to exit and joined. 60 */ 61 void shutdown(); 62 63 /** 64 * When the scrubber is done running the requested scrub task it 65 * will call this callback notifying that it is done. 66 * 67 * @param engine the requested engine 68 * @param destroy set to true if the engine should be destroyed 69 */ 70 void notifyScrubComplete(struct default_engine* engine, bool destroy); 71 72protected: 73 /** 74 * Wait for the scrubber task to be idle. You <b>must</b> hold the 75 * mutex while calling this function. 76 */ 77 void waitForScrubberToBeIdle(std::unique_lock<std::mutex>& lck); 78 79private: 80 /** single mutex protects all members */ 81 std::mutex lock; 82 83 /** condition variable used from the scrubber to notify the engine */ 84 std::condition_variable cond; 85 86 /** Handle to the scrubber task being used to preform the operations */ 87 ScrubberTask scrubberTask; 88 89 /** Are we currently shutting down? (Note: We should refactor the clients 90 * using the class to ensure that this isn't a problem. Given that we can't 91 * restart the task it doesn't really make any sense if we have a race 92 * with one client trying to delete a bucket, and another one trying to 93 * shut down the object... 94 */ 95 bool shuttingdown; 96 97 /** Handle of all of the instances created of default engine */ 98 std::unordered_set<struct default_engine*> engines; 99}; 100 101extern "C" { 102#endif 103 104/* 105 * Create a new engine instance. 106 * Returns NULL for failure. 107 */ 108struct default_engine* engine_manager_create_engine(); 109 110/* 111 * Delete the engine instance. 112 * Deletion is performed by a background thread. 113 * On return from this method the caller must not use the pointer as 114 * it will be deleted at any time. 115 */ 116void engine_manager_delete_engine(struct default_engine* engine); 117 118/* 119 * Request that a scrub of the engine is performed. 120 * Scrub is perfromed by a background thread. 121 */ 122void engine_manager_scrub_engine(struct default_engine* engine); 123 124/* 125 * Perform global shutdown in prepration for unloading of the shared object. 126 * This method will block until background threads are joined. 127 */ 128void engine_manager_shutdown(); 129 130#ifdef __cplusplus 131} 132#endif 133