1 // 2 // This file is part of the aMule Project. 3 // 4 // Copyright (c) 2006-2011 Mikkel Schubert ( xaignar@amule.org / http://www.amule.org ) 5 // Copyright (c) 2006-2011 aMule Team ( admin@amule.org / http://www.amule.org ) 6 // 7 // Any parts of this program derived from the xMule, lMule or eMule project, 8 // or contributed by third-party developers are copyrighted by their 9 // respective authors. 10 // 11 // This program is free software; you can redistribute it and/or modify 12 // it under the terms of the GNU General Public License as published by 13 // the Free Software Foundation; either version 2 of the License, or 14 // (at your option) any later version. 15 // 16 // This program is distributed in the hope that it will be useful, 17 // but WITHOUT ANY WARRANTY; without even the implied warranty of 18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 // GNU General Public License for more details. 20 // 21 // You should have received a copy of the GNU General Public License 22 // along with this program; if not, write to the Free Software 23 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 24 // 25 26 27 #ifndef THREADSCHEDULER_H 28 #define THREADSCHEDULER_H 29 30 #include <deque> 31 #include <map> 32 33 #include "Types.h" 34 #include "MuleThread.h" 35 36 37 class CThreadTask; 38 39 40 //! The priority values of tasks. 41 enum ETaskPriority 42 { 43 ETP_Low = 0, 44 ETP_Normal, 45 ETP_High, 46 //! For tasks such as finding shared files and ipfilter.dat loading only. 47 ETP_Critical 48 }; 49 50 51 /** 52 * This class mananges scheduling of background tasks. 53 * 54 * Currently it is assumed that all tasks are IO intensive, 55 * so that only a single task is allowed to proceed at any 56 * one time. All threads are run in lowest priority mode. 57 * 58 * Tasks are sorted by priority (see ETaskPriority) and age. 59 * 60 * Note that the scheduler starts in suspended mode, in 61 * which tasks are queued but not executed. Call Start() 62 * to begin execution of the tasks. 63 */ 64 class CThreadScheduler 65 { 66 public: 67 /** Starts execution of queued tasks. */ 68 static void Start(); 69 70 /** 71 * Terminates task execution and frees the scheduler object. 72 * 73 * Tasks added after this are discarded. 74 */ 75 static void Terminate(); 76 77 78 /** 79 * Adds a new task to the queue, returning true if the task was queued. 80 * 81 * Before the task is queued, it is checked against the 82 * existing tasks based on type and description. If an 83 * matching task already exists, this task-object is 84 * discarded. The task is also discarded if the scheduler 85 * has been terminated. If 'overwrite' is true, any 86 * existing duplicate task is dropped, and if already 87 * running, terminated. 88 * 89 * Note: This function takes ownership of the task. 90 * 91 * @see Start 92 * @see Terminate 93 */ 94 static bool AddTask(CThreadTask* task, bool overwrite = false); 95 96 private: 97 CThreadScheduler(); 98 ~CThreadScheduler(); 99 100 /** Returns the number of tasks on the queue. */ 101 size_t GetTaskCount() const; 102 103 /** Tries to add the given task to the queue, returning true on success. */ 104 bool DoAddTask(CThreadTask* task, bool overwrite); 105 106 /** Creates the actual scheduler thread if none exist. */ 107 void CreateSchedulerThread(); 108 109 /** Entry function called via internal thread-object. */ 110 void* Entry(); 111 112 //! Contains a task and its age. 113 typedef std::pair<CThreadTask*, uint32> CEntryPair; 114 115 //! List of currently scheduled tasks. 116 std::deque<CEntryPair> m_tasks; 117 118 //! Specifies if tasks should be resorted by priority. 119 bool m_tasksDirty; 120 121 typedef std::map<wxString, CThreadTask*> CDescMap; 122 typedef std::map<wxString, CDescMap> CTypeMap; 123 //! Map of current task by type -> desc. Used to avoid duplicate tasks. 124 CTypeMap m_taskDescs; 125 126 //! The actual worker thread. 127 CMuleThread* m_thread; 128 //! The currently running task, if any. 129 CThreadTask* m_currentTask; 130 131 friend class CTaskThread; 132 friend struct CTaskSorter; 133 }; 134 135 136 /** 137 * Base-class of all threaded tasks. 138 * 139 * This class acts as a pseudo-thread, and is transparently 140 * executed on a worker thread by the CThreadScheduler 141 * class. 142 * 143 * Note that the task type should be an unique description 144 * of the task type, as it is used to detect completion of 145 * all tasks of a given type and in duplicate detection 146 * with the description. The description should be unique 147 * for the given task, such that duplicates can be discovered. 148 */ 149 class CThreadTask 150 { 151 public: 152 /** 153 * @param type Should be a name constant among tasks of the type (hashing, completion, etc). 154 * @param desc Should be an unique description for this task, for detecting duplicates. 155 * @param priority Decides how soon the task will be carried out. 156 */ 157 CThreadTask(const wxString& type, const wxString& desc, ETaskPriority priority = ETP_Normal); 158 159 /** Needed since CThreadScheduler only works with CThreadTask pointers. */ 160 virtual ~CThreadTask(); 161 162 /** Returns the task type, used for debugging and duplicate detection. */ 163 const wxString& GetType() const; 164 165 /** Returns the task description, used for debugging and duplicate detection. */ 166 const wxString& GetDesc() const; 167 168 /** Returns the priority of the task. Used when selecting the next task. */ 169 ETaskPriority GetPriority() const; 170 171 protected: 172 //! @see wxThread::Entry 173 virtual void Entry() = 0; 174 175 /** Called when the last task of a specific type has been completed. */ 176 virtual void OnLastTask(); 177 178 /** @see wxThread::OnExit */ 179 virtual void OnExit(); 180 181 /** @see wxThread::TestDestroy */ 182 bool TestDestroy() const; 183 184 private: 185 wxString m_type; 186 wxString m_desc; 187 ETaskPriority m_priority; 188 189 //! The owner (scheduler), used when calling TestDestroy. 190 CMuleThread* m_owner; 191 //! Specifies if the specifc task should be aborted. 192 bool m_abort; 193 194 friend class CThreadScheduler; 195 }; 196 197 #endif 198 // File_checked_for_headers 199