1 #ifndef _GLIBMM_THREADPOOL_H 2 #define _GLIBMM_THREADPOOL_H 3 4 /* Copyright (C) 2002 The gtkmm Development Team 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include <glibmmconfig.h> 21 22 #ifndef GLIBMM_DISABLE_DEPRECATED 23 24 #include <sigc++/sigc++.h> 25 26 extern "C" { 27 using GThreadPool = struct _GThreadPool; 28 } 29 30 namespace Glib 31 { 32 33 /** @defgroup ThreadPools Thread Pools 34 * Pools of threads to execute work concurrently. 35 * 36 * @deprecated This is deprecated in favor of the standard C++ concurrency API in C++11 and C++14. 37 * 38 * @{ 39 */ 40 41 // TODO: Is std::async() an appropriate replacement to mention for this deprecated API? 42 43 /** A pool of threads to execute work concurrently. 44 * 45 * @deprecated This is deprecated in favor of the standard C++ concurrency API in C++11 and C++14. 46 */ 47 class GLIBMM_API ThreadPool 48 { 49 public: 50 /** Constructs a new thread pool. 51 * Whenever you call ThreadPool::push(), either a new thread is created or an 52 * unused one is reused. At most @a max_threads threads are running 53 * concurrently for this thread pool. @a max_threads = -1 allows 54 * unlimited threads to be created for this thread pool. 55 * 56 * The parameter @a exclusive determines, whether the thread pool owns all 57 * threads exclusive or whether the threads are shared globally. If @a 58 * exclusive is <tt>true</tt>, @a max_threads threads are started immediately 59 * and they will run exclusively for this thread pool until it is destroyed 60 * by ~ThreadPool(). If @a exclusive is <tt>false</tt>, threads are created 61 * when needed and shared between all non-exclusive thread pools. This 62 * implies that @a max_threads may not be -1 for exclusive thread pools. 63 * 64 * @param max_threads The maximal number of threads to execute concurrently 65 * in the new thread pool, -1 means no limit. 66 * @param exclusive Should this thread pool be exclusive? 67 * @throw Glib::ThreadError An error can only occur when @a exclusive is 68 * set to <tt>true</tt> and not all @a max_threads threads could be created. 69 */ 70 explicit ThreadPool(int max_threads = -1, bool exclusive = false); 71 virtual ~ThreadPool() noexcept; 72 73 // See http://bugzilla.gnome.org/show_bug.cgi?id=512348 about the sigc::trackable issue. 74 // TODO: At the next ABI break, consider changing const sigc::slot<void>& slot 75 // to const std::function<void()>& func, if it can be assumed that all supported 76 // compilers understand the C++11 template class std::function<>. 77 /** Inserts @a slot into the list of tasks to be executed by the pool. 78 * When the number of currently running threads is lower than the maximal 79 * allowed number of threads, a new thread is started (or reused). Otherwise 80 * @a slot stays in the queue until a thread in this pool finishes its 81 * previous task and processes @a slot. 82 * 83 * Because sigc::trackable is not thread-safe, if the slot represents a 84 * non-static class method and is created by sigc::mem_fun(), the class concerned 85 * should not derive from sigc::trackable. You can use, say, boost::bind() or, 86 * in C++11, std::bind() or a C++11 lambda expression instead of sigc::mem_fun(). 87 * 88 * @param slot A new task for the thread pool. 89 * @throw Glib::ThreadError An error can only occur when a new thread 90 * couldn't be created. In that case @a slot is simply appended to the 91 * queue of work to do. 92 */ 93 void push(const sigc::slot<void>& slot); 94 95 /** Sets the maximal allowed number of threads for the pool. 96 * A value of -1 means that the maximal number of threads is unlimited. 97 * Setting @a max_threads to 0 means stopping all work for pool. It is 98 * effectively frozen until @a max_threads is set to a non-zero value again. 99 * 100 * A thread is never terminated while it is still running. Instead the 101 * maximal number of threads only has effect for the allocation of new 102 * threads in ThreadPool::push(). A new thread is allocated whenever the 103 * number of currently running threads in the pool is smaller than the 104 * maximal number. 105 * 106 * @param max_threads A new maximal number of threads for the pool. 107 * @throw Glib::ThreadError An error can only occur when a new thread 108 * couldn't be created. 109 */ 110 void set_max_threads(int max_threads); 111 112 /** Returns the maximal number of threads for the pool. 113 * @return The maximal number of threads. 114 */ 115 int get_max_threads() const; 116 117 /** Returns the number of threads currently running in the pool. 118 * @return The number of threads currently running. 119 */ 120 unsigned int get_num_threads() const; 121 122 /** Returns the number of tasks still unprocessed in the pool. 123 * @return The number of unprocessed tasks. 124 */ 125 unsigned int unprocessed() const; 126 127 /** Returns whether all threads are exclusive to this pool. 128 * @return Whether all threads are exclusive to this pool. 129 */ 130 bool get_exclusive() const; 131 132 /** Frees all resources allocated for the pool. 133 * If @a immediately is <tt>true</tt>, no new task is processed. Otherwise the 134 * pool is not freed before the last task is processed. Note however, that no 135 * thread of this pool is interrupted while processing a task. Instead at least 136 * all still running threads can finish their tasks before the pool is freed. 137 * 138 * This method does not return before all tasks to be processed (dependent on 139 * @a immediately, whether all or only the currently running) are ready. 140 * After calling shutdown() the pool must not be used anymore. 141 * 142 * @param immediately Should the pool shut down immediately? 143 */ 144 void shutdown(bool immediately = false); 145 146 /** Sets the maximal number of unused threads to @a max_threads. 147 * If @a max_threads is -1, no limit is imposed on the number of unused threads. 148 * @param max_threads Maximal number of unused threads. 149 */ 150 static void set_max_unused_threads(int max_threads); 151 152 /** Returns the maximal allowed number of unused threads. 153 * @return The maximal number of unused threads. 154 */ 155 static int get_max_unused_threads(); 156 157 /** Returns the number of currently unused threads. 158 * @return The number of currently unused threads. 159 */ 160 static unsigned int get_num_unused_threads(); 161 162 /** Stops all currently unused threads. 163 * This does not change the maximal number of unused threads. This function can 164 * be used to regularly stop all unused threads e.g. from Glib::signal_timeout(). 165 */ 166 static void stop_unused_threads(); 167 gobj()168 GThreadPool* gobj() { return gobject_; } gobj()169 const GThreadPool* gobj() const { return gobject_; } 170 171 #ifndef DOXYGEN_SHOULD_SKIP_THIS 172 class SlotList; 173 #endif 174 175 private: 176 GThreadPool* gobject_; 177 SlotList* slot_list_; 178 179 ThreadPool(const ThreadPool&); 180 ThreadPool& operator=(const ThreadPool&); 181 }; 182 183 /** @} group ThreadPools */ 184 185 /***************************************************************************/ 186 /* inline implementation */ 187 /***************************************************************************/ 188 189 #ifndef DOXYGEN_SHOULD_SKIP_THIS 190 191 /**** Glib::Private ********************************************************/ 192 193 #endif /* DOXYGEN_SHOULD_SKIP_THIS */ 194 195 } // namespace Glib 196 197 #endif // GLIBMM_DISABLE_DEPRECATED 198 199 #endif /* _GLIBMM_THREADPOOL_H */ 200