diff --git a/code/nel/tools/pipeline/service/build_task_queue.cpp b/code/nel/tools/pipeline/service/build_task_queue.cpp index 6040e3d32..08a2f93f7 100644 --- a/code/nel/tools/pipeline/service/build_task_queue.cpp +++ b/code/nel/tools/pipeline/service/build_task_queue.cpp @@ -49,7 +49,7 @@ CBuildTaskQueue::CBuildTaskQueue() : m_QueueId(0) CBuildTaskQueue::~CBuildTaskQueue() { - + resetQueue(); } namespace { @@ -58,14 +58,15 @@ namespace { } /* anonymous namespace */ -void CBuildTaskQueue::loadQueue(CPipelineWorkspace *workspace) +void CBuildTaskQueue::loadQueue(CPipelineWorkspace *workspace, bool bypassDependencyError) { m_Mutex.lock(); nlassert(m_Tasks.empty()); ++m_QueueId; + m_BypassDependencyError = bypassDependencyError; const std::map &projects = workspace->getProjects(); - + std::map > builtTaskByProjectAndPlugin; for (std::map::const_iterator pr_it = projects.begin(), pr_end = projects.end(); pr_it != pr_end; ++pr_it) @@ -123,30 +124,94 @@ CBuildTaskInfo *CBuildTaskQueue::getTaskInfo(uint32 taskId) return m_Tasks[id.Sub.Task]; } -CBuildTaskInfo *CBuildTaskQueue::getTaskForSlave(const std::vector &availablePlugins, bool bypassDependencyError) +CBuildTaskInfo *CBuildTaskQueue::getTaskForSlave(const std::vector &availablePlugins) { m_Mutex.lock(); - std::vector availableTasks; - createBuildableTaskList(availableTasks, bypassDependencyError); + std::vector availableTasks; + createBuildableTaskList(availableTasks, m_BypassDependencyError); sortBuildableTaskListByMostDependents(availableTasks); - for (std::vector::iterator it = availableTasks.begin(), end = availableTasks.end(); it != end; ++it) + for (std::vector::iterator it = availableTasks.begin(), end = availableTasks.end(); it != end; ++it) { - CBuildTaskInfo *task = m_Tasks[(*it).Sub.Task]; + CBuildTaskInfo *task = (*it); if (find(availablePlugins.begin(), availablePlugins.end(), task->ProcessPluginId) != availablePlugins.end()) { + task->State = TASK_WORKING; m_Mutex.unlock(); - return m_Tasks[(*it).Sub.Task]; + return task; } } m_Mutex.unlock(); return NULL; // no task available for slave. } -uint CBuildTaskQueue::countRemainingBuildableTasks(bool bypassDependencyError) +void CBuildTaskQueue::abortedTask(uint32 taskId) +{ + m_Mutex.lock(); + CBuildTaskInfo *info = getTaskInfo(taskId); + info->State = TASK_ABORTED; + m_Mutex.unlock(); +} + +void CBuildTaskQueue::rejectedTask(uint32 taskId) +{ + m_Mutex.lock(); + CBuildTaskInfo *info = getTaskInfo(taskId); + info->State = TASK_WAITING; // make available again + m_Mutex.unlock(); +} + +void CBuildTaskQueue::erroredTask(uint32 taskId) +{ + m_Mutex.lock(); + CBuildTaskInfo *info = getTaskInfo(taskId); + info->State = TASK_ERRORED; + m_Mutex.unlock(); +} + +void CBuildTaskQueue::successTask(uint32 taskId) +{ + m_Mutex.lock(); + CBuildTaskInfo *info = getTaskInfo(taskId); + info->State = TASK_SUCCESS; + m_Mutex.unlock(); +} + +void CBuildTaskQueue::abortQueue() +{ + m_Mutex.lock(); + for (std::vector::iterator it = m_Tasks.begin(), end = m_Tasks.end(); it != end; ++it) + { + if ((*it)->State == TASK_WAITING) + (*it)->State = TASK_ABORTED; + } + m_Mutex.unlock(); +} + +void CBuildTaskQueue::resetQueue() { m_Mutex.lock(); - std::vector availableTasks; - createBuildableTaskList(availableTasks, bypassDependencyError); + + // count remaining and working first and assert its 0 + std::vector availableTasks; + createBuildableTaskList(availableTasks, m_BypassDependencyError); + uint nb = availableTasks.size(); + for (std::vector::iterator it = m_Tasks.begin(), end = m_Tasks.end(); it != end; ++it) + if ((*it)->State == TASK_WORKING) + ++nb; + nlassert(nb == 0); + + for (std::vector::iterator it = m_Tasks.begin(), end = m_Tasks.end(); it != end; ++it) + delete (*it); + m_Tasks.clear(); + + m_Mutex.unlock(); +} + +uint CBuildTaskQueue::countRemainingBuildableTasks() +{ + m_Mutex.lock(); + std::vector availableTasks; + createBuildableTaskList(availableTasks, m_BypassDependencyError); m_Mutex.unlock(); return availableTasks.size(); } @@ -162,11 +227,11 @@ uint CBuildTaskQueue::countWorkingTasks() return nb; } -uint CBuildTaskQueue::countRemainingBuildableTasksAndWorkingTasks(bool bypassDependencyError) +uint CBuildTaskQueue::countRemainingBuildableTasksAndWorkingTasks() { m_Mutex.lock(); - std::vector availableTasks; - createBuildableTaskList(availableTasks, bypassDependencyError); + std::vector availableTasks; + createBuildableTaskList(availableTasks, m_BypassDependencyError); uint nb = availableTasks.size(); for (std::vector::iterator it = m_Tasks.begin(), end = m_Tasks.end(); it != end; ++it) if ((*it)->State == TASK_WORKING) @@ -175,6 +240,14 @@ uint CBuildTaskQueue::countRemainingBuildableTasksAndWorkingTasks(bool bypassDep return nb; } +void CBuildTaskQueue::listTaskQueueByMostDependents(std::vector &result) +{ + result.clear(); + result.reserve(m_Tasks.size()); + /*copy(m_Tasks.begin(), m_Tasks.end(), result); + sortBuildableTaskListByMostDependents(result);*/ +} + void CBuildTaskQueue::countDependents(uint &dependentResult, CBuildTaskInfo *taskInfo) { uint nb = 0; @@ -203,7 +276,7 @@ bool CBuildTaskQueue::doesTaskDependOnTask(CBuildTaskInfo *doesThisTask, CBuildT return false; } -void CBuildTaskQueue::createBuildableTaskList(std::vector &result, bool bypassError) +void CBuildTaskQueue::createBuildableTaskList(std::vector &result, bool bypassError) { // makes a list of tasks where all dependencies are ready result.clear(); @@ -219,7 +292,7 @@ void CBuildTaskQueue::createBuildableTaskList(std::vector &result, if (((dependencyState == TASK_ERRORED) && !bypassError) || dependencyState == TASK_WAITING || dependencyState == TASK_WORKING - || dependencyState == TASK_ABORTED) + || (dependencyState == TASK_ABORTED && !bypassError)) { ok = false; break; @@ -227,20 +300,20 @@ void CBuildTaskQueue::createBuildableTaskList(std::vector &result, } if (ok) { - result.push_back((*it)->Id); + result.push_back((*it)); } } } // sortBuildableTaskListByMostDependents(result); } -void CBuildTaskQueue::sortBuildableTaskListByMostDependents(std::vector &result) +void CBuildTaskQueue::sortBuildableTaskListByMostDependents(std::vector &result) { // brings most urgent tasks on top std::vector dependentsCache; dependentsCache.resize(result.size()); for (std::vector::size_type i = 0; i < dependentsCache.size(); ++i) - countDependents(dependentsCache[i], m_Tasks[result[i].Sub.Task]); + countDependents(dependentsCache[i], result[i]); uint sc; do { diff --git a/code/nel/tools/pipeline/service/build_task_queue.h b/code/nel/tools/pipeline/service/build_task_queue.h index 87c4a39c0..d25f1e39c 100644 --- a/code/nel/tools/pipeline/service/build_task_queue.h +++ b/code/nel/tools/pipeline/service/build_task_queue.h @@ -91,23 +91,35 @@ protected: boost::mutex m_Mutex; std::vector m_Tasks; + bool m_BypassDependencyError; public: CBuildTaskQueue(); virtual ~CBuildTaskQueue(); - void loadQueue(CPipelineWorkspace *workspace); + void loadQueue(CPipelineWorkspace *workspace, bool bypassDependencyError); CBuildTaskInfo *getTaskInfo(uint32 taskId); - CBuildTaskInfo *getTaskForSlave(const std::vector &availablePlugins, bool bypassDependencyError); + /// Gets task for slave, state is set to TASK_WORKING, returns NULL if none available + CBuildTaskInfo *getTaskForSlave(const std::vector &availablePlugins); + void abortedTask(uint32 taskId); + void rejectedTask(uint32 taskId); + void erroredTask(uint32 taskId); + void successTask(uint32 taskId); - uint countRemainingBuildableTasks(bool bypassDependencyError); + void abortQueue(); + void resetQueue(); + + uint countRemainingBuildableTasks(); uint countWorkingTasks(); // when next are 0 the build should stop - uint countRemainingBuildableTasksAndWorkingTasks(bool bypassDependencyError); + uint countRemainingBuildableTasksAndWorkingTasks(); + + // informational listing for sending initial task listing to terminals + void listTaskQueueByMostDependents(std::vector &result); private: - void countDependencies(uint &waitingResult, uint &failAbortResult, CBuildTaskInfo *taskInfo); + // void countDependencies(uint &waitingResult, uint &failAbortResult, CBuildTaskInfo *taskInfo); /// Recursively count the number of tasks that depend on this task. void countDependents(uint &dependentResult, CBuildTaskInfo *taskInfo); @@ -115,8 +127,8 @@ private: bool doesTaskDependOnTask(CBuildTaskInfo *doesThisTask, CBuildTaskInfo *dependOnThisTask); - void createBuildableTaskList(std::vector &result, bool bypassError); - void sortBuildableTaskListByMostDependents(std::vector &result); + void createBuildableTaskList(std::vector &result, bool bypassError); + void sortBuildableTaskListByMostDependents(std::vector &result); }; /* class CBuildTaskQueue */