Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "cartographer/common/task.h"
00018
00019 namespace cartographer {
00020 namespace common {
00021
00022 Task::~Task() {
00023
00024 if (state_ != NEW && state_ != COMPLETED) {
00025 LOG(WARNING) << "Delete Task between dispatch and completion.";
00026 }
00027 }
00028
00029 Task::State Task::GetState() {
00030 absl::MutexLock locker(&mutex_);
00031 return state_;
00032 }
00033
00034 void Task::SetWorkItem(const WorkItem& work_item) {
00035 absl::MutexLock locker(&mutex_);
00036 CHECK_EQ(state_, NEW);
00037 work_item_ = work_item;
00038 }
00039
00040 void Task::AddDependency(std::weak_ptr<Task> dependency) {
00041 std::shared_ptr<Task> shared_dependency;
00042 {
00043 absl::MutexLock locker(&mutex_);
00044 CHECK_EQ(state_, NEW);
00045 if ((shared_dependency = dependency.lock())) {
00046 ++uncompleted_dependencies_;
00047 }
00048 }
00049 if (shared_dependency) {
00050 shared_dependency->AddDependentTask(this);
00051 }
00052 }
00053
00054 void Task::SetThreadPool(ThreadPoolInterface* thread_pool) {
00055 absl::MutexLock locker(&mutex_);
00056 CHECK_EQ(state_, NEW);
00057 state_ = DISPATCHED;
00058 thread_pool_to_notify_ = thread_pool;
00059 if (uncompleted_dependencies_ == 0) {
00060 state_ = DEPENDENCIES_COMPLETED;
00061 CHECK(thread_pool_to_notify_);
00062 thread_pool_to_notify_->NotifyDependenciesCompleted(this);
00063 }
00064 }
00065
00066 void Task::AddDependentTask(Task* dependent_task) {
00067 absl::MutexLock locker(&mutex_);
00068 if (state_ == COMPLETED) {
00069 dependent_task->OnDependenyCompleted();
00070 return;
00071 }
00072 bool inserted = dependent_tasks_.insert(dependent_task).second;
00073 CHECK(inserted) << "Given dependency is already a dependency.";
00074 }
00075
00076 void Task::OnDependenyCompleted() {
00077 absl::MutexLock locker(&mutex_);
00078 CHECK(state_ == NEW || state_ == DISPATCHED);
00079 --uncompleted_dependencies_;
00080 if (uncompleted_dependencies_ == 0 && state_ == DISPATCHED) {
00081 state_ = DEPENDENCIES_COMPLETED;
00082 CHECK(thread_pool_to_notify_);
00083 thread_pool_to_notify_->NotifyDependenciesCompleted(this);
00084 }
00085 }
00086
00087 void Task::Execute() {
00088 {
00089 absl::MutexLock locker(&mutex_);
00090 CHECK_EQ(state_, DEPENDENCIES_COMPLETED);
00091 state_ = RUNNING;
00092 }
00093
00094
00095 if (work_item_) {
00096 work_item_();
00097 }
00098
00099 absl::MutexLock locker(&mutex_);
00100 state_ = COMPLETED;
00101 for (Task* dependent_task : dependent_tasks_) {
00102 dependent_task->OnDependenyCompleted();
00103 }
00104 }
00105
00106 }
00107 }