Skip to content

Commit 287684d

Browse files
Fix issue where cache is emptied by other threads after refresh causing segfault when popping environment on empty queue
1 parent 92cd20a commit 287684d

File tree

2 files changed

+27
-20
lines changed

2 files changed

+27
-20
lines changed

tesseract_environment/include/tesseract_environment/environment_cache.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ class DefaultEnvironmentCache : public EnvironmentCache
118118

119119
/** @brief The mutex used when reading and writing to cache_ */
120120
mutable std::shared_mutex cache_mutex_;
121+
122+
/** @brief This does not take a lock */
123+
void refreshCacheHelper() const;
121124
};
122125
} // namespace tesseract_environment
123126

tesseract_environment/src/environment_cache.cpp

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* @file environment_cache.cpp
3-
* @brief A environment cache
3+
* @brief Default environment cache
44
*
55
* @author Levi Armstrong
66
* @date December 3, 2020
@@ -28,7 +28,8 @@
2828

2929
namespace tesseract_environment
3030
{
31-
DefaultEnvironmentCache::DefaultEnvironmentCache(Environment::ConstPtr env, std::size_t cache_size)
31+
DefaultEnvironmentCache::DefaultEnvironmentCache(tesseract_environment::Environment::ConstPtr env,
32+
std::size_t cache_size)
3233
: env_(std::move(env)), cache_size_(cache_size)
3334
{
3435
}
@@ -44,8 +45,28 @@ long DefaultEnvironmentCache::getCacheSize() const { return static_cast<long>(ca
4445
void DefaultEnvironmentCache::refreshCache() const
4546
{
4647
std::unique_lock<std::shared_mutex> lock(cache_mutex_);
47-
tesseract_environment::Environment::UPtr env;
48+
refreshCacheHelper();
49+
}
50+
51+
tesseract_environment::Environment::UPtr DefaultEnvironmentCache::getCachedEnvironment() const
52+
{
53+
tesseract_scene_graph::SceneState current_state = env_->getState();
54+
55+
std::unique_lock<std::shared_mutex> lock(cache_mutex_);
56+
refreshCacheHelper(); // This is to make sure the cached items are updated if needed
57+
assert(!cache_.empty());
58+
tesseract_environment::Environment::UPtr t = std::move(cache_.back());
59+
// Update to the current joint values
60+
t->setState(current_state.joints);
61+
62+
cache_.pop_back();
4863

64+
return t;
65+
}
66+
67+
void DefaultEnvironmentCache::refreshCacheHelper() const
68+
{
69+
tesseract_environment::Environment::UPtr env;
4970
auto lock_read = env_->lockRead();
5071
int rev = env_->getRevision();
5172
if (rev != cache_env_revision_ || cache_.empty())
@@ -67,21 +88,4 @@ void DefaultEnvironmentCache::refreshCache() const
6788
}
6889
}
6990

70-
Environment::UPtr DefaultEnvironmentCache::getCachedEnvironment() const
71-
{
72-
// This is to make sure the cached items are updated if needed
73-
refreshCache();
74-
75-
tesseract_scene_graph::SceneState current_state = env_->getState();
76-
77-
std::unique_lock<std::shared_mutex> lock(cache_mutex_);
78-
tesseract_environment::Environment::UPtr t = std::move(cache_.back());
79-
80-
// Update to the current joint values
81-
t->setState(current_state.joints);
82-
83-
cache_.pop_back();
84-
85-
return t;
86-
}
8791
} // namespace tesseract_environment

0 commit comments

Comments
 (0)