task.cc
Go to the documentation of this file.
00001 /*
00002  * Copyright 2018 The Cartographer Authors
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *      http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "cartographer/common/task.h"
00018 
00019 namespace cartographer {
00020 namespace common {
00021 
00022 Task::~Task() {
00023   // TODO(gaschler): Relax some checks after testing.
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   // Execute the work item.
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 }  // namespace common
00107 }  // namespace cartographer


cartographer
Author(s): The Cartographer Authors
autogenerated on Thu May 9 2019 02:27:36