/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #ifndef _THRIFT_CONCURRENCY_THREADMANAGER_H_ #define _THRIFT_CONCURRENCY_THREADMANAGER_H_ 1 #include #include #include namespace apache { namespace thrift { namespace concurrency { class Runnable; class ThreadFactory; /** * ThreadManager class * * This class manages a pool of threads. It uses a ThreadFactory to create * threads. It never actually creates or destroys worker threads, rather * It maintains statistics on number of idle threads, number of active threads, * task backlog, and average wait and service times and informs the PoolPolicy * object bound to instances of this manager of interesting transitions. It is * then up the PoolPolicy object to decide if the thread pool size needs to be * adjusted and call this object addWorker and removeWorker methods to make * changes. * * This design allows different policy implementations to used this code to * handle basic worker thread management and worker task execution and focus on * policy issues. The simplest policy, StaticPolicy, does nothing other than * create a fixed number of threads. */ class ThreadManager { protected: ThreadManager() {} public: class Task; typedef std::tr1::function)> ExpireCallback; typedef std::tr1::function InitCallback; virtual ~ThreadManager() {} /** * Starts the thread manager. Verifies all attributes have been properly * initialized, then allocates necessary resources to begin operation */ virtual void start() = 0; /** * Stops the thread manager. Aborts all remaining unprocessed task, shuts * down all created worker threads, and releases all allocated resources. * This method blocks for all worker threads to complete, thus it can * potentially block forever if a worker thread is running a task that * won't terminate. */ virtual void stop() = 0; /** * Joins the thread manager. This is the same as stop, except that it will * wait until all the tasks have finished, rather than aborting the tasks. */ virtual void join() = 0; enum STATE { UNINITIALIZED, STARTING, STARTED, JOINING, STOPPING, STOPPED }; virtual const STATE state() const = 0; virtual boost::shared_ptr threadFactory() const = 0; virtual void threadFactory(boost::shared_ptr value) = 0; virtual void addWorker(size_t value=1) = 0; virtual void removeWorker(size_t value=1) = 0; /** * Gets the current number of idle worker threads */ virtual size_t idleWorkerCount() const = 0; /** * Gets the current number of total worker threads */ virtual size_t workerCount() const = 0; /** * Gets the current number of pending tasks */ virtual size_t pendingTaskCount() const = 0; /** * Gets the current number of pending and executing tasks */ virtual size_t totalTaskCount() const = 0; /** * Gets the maximum pending task count. 0 indicates no maximum */ virtual size_t pendingTaskCountMax() const = 0; /** * Gets the number of tasks which have been expired without being run. */ virtual size_t expiredTaskCount() = 0; /** * Adds a task to be executed at some time in the future by a worker thread. * * This method will block if pendingTaskCountMax() in not zero and * pendingTaskCount() is greater than or equal to pendingTaskCountMax(). If * this method is called in the context of a ThreadManager worker thread it * will throw a TooManyPendingTasksException * * @param task The task to queue for execution * * @param timeout Time to wait in milliseconds to add a task when a * pending-task-count is specified. Specific cases: * timeout = 0 : Wait forever to queue task. * timeout = -1 : Return immediately if pending task count exceeds specified * max * @param expiration when nonzero, the number of milliseconds the task is * valid to be run; if exceeded, the task will be dropped off the queue and * not run. * * @throws TooManyPendingTasksException Pending task count exceeds max * pending task count */ virtual void add(boost::shared_ptrtask, int64_t timeout=0LL, int64_t expiration=0LL) = 0; /** * Removes a pending task */ virtual void remove(boost::shared_ptr task) = 0; /** * Remove the next pending task which would be run. * * @return the task removed. */ virtual boost::shared_ptr removeNextPending() = 0; /** * Set a callback to be called when a task is expired and not run. * * @param expireCallback a function called with the shared_ptr for * the expired task. */ virtual void setExpireCallback(ExpireCallback expireCallback) = 0; /** * Set a callback to be called when a worker thread is created. */ virtual void setThreadInitCallback(InitCallback initCallback) = 0; static boost::shared_ptr newThreadManager(); /** * Creates a simple thread manager the uses count number of worker threads * and has a pendingTaskCountMax maximum pending tasks. The default, 0, * specified no limit on pending tasks */ static boost::shared_ptr newSimpleThreadManager(size_t count = 4, size_t pendingTaskCountMax = 0, bool enableTaskStats = false); /** * Get an internal statistics. * * @param waitTimeUs - average time (us) task spent in a queue * @param runTimeUs - average time (us) task spent running * @param maxItems - max items collected for stats */ virtual void getStats(int64_t& waitTimeUs, int64_t& runTimeUs, int64_t maxItems) { waitTimeUs = 0; runTimeUs = 0; } class Task; class Worker; class Impl; }; }}} // apache::thrift::concurrency #endif // #ifndef _THRIFT_CONCURRENCY_THREADMANAGER_H_