roslib: #2220 invalidate cache if pkg dir does not exist

This commit is contained in:
Ken Conley 2009-12-24 00:13:59 +00:00
parent 471be904d1
commit 32a673605c
2 changed files with 42 additions and 14 deletions

View File

@ -140,7 +140,11 @@ _pkg_dir_cache = {}
def get_pkg_dir(package, required=True, ros_root=None, ros_package_path=None):
"""
Locate directory package is stored in
Locate directory package is stored in. This routine uses an
internal cache.
NOTE: cache does *not* rebuild if packages are relocated after
this process is initiated.
@param package: package name
@type package: str
@ -183,10 +187,14 @@ def get_pkg_dir(package, required=True, ros_root=None, ros_package_path=None):
# now that we've resolved the args, check the cache
if package in _pkg_dir_cache:
dir, rr, rpp = _pkg_dir_cache[package]
dir_, rr, rpp = _pkg_dir_cache[package]
if rr == ros_root and rpp == ros_package_path:
return dir
if os.path.isfile(os.path.join(dir_, MANIFEST_FILE)):
return dir_
else:
# invalidate cache
_invalidate_cache(_pkg_dir_cache)
rpout, rperr = Popen([rospack, 'find', package], \
stdout=PIPE, stderr=PIPE, env=penv).communicate()
@ -304,6 +312,11 @@ def _update_rospack_cache():
ros_package_path = os.environ.get(ROS_PACKAGE_PATH, '')
return _read_rospack_cache(cache, ros_root, ros_package_path)
def _invalidate_cache(cache):
# I've only made this a separate routine because roslib.packages should really be using
# the roslib.stacks cache implementation instead with the separate cache marker
cache.clear()
def _read_rospack_cache(cache, ros_root, ros_package_path):
"""
Read in rospack_cache data into cache
@ -359,6 +372,10 @@ def list_pkgs(pkg_dirs=None, cache=None):
if cache is None:
# if cache is not specified, we use global cache instead
# TODO: this cache can be out-of-date if rospack has not
# been run recently. Figure out correct approach for
# out-of-date cache.
# TODO: we don't have any logic go populate user-specified
# cache in most optimal way
cache = _pkg_dir_cache

View File

@ -119,22 +119,33 @@ def get_stack_dir(stack):
@rtype: str
"""
# this cache implementation is technically incorrect. it's
# possible to get incorrect results by manipulating environment
# overrides from multiple threads. for the sake of future
# implementations, we provide an environment check, but within
# this implementation it does not provide much guarantee
# it's possible to get incorrect results from this cache
# implementation by manipulating the environment and calling this
# from multiple threads. as that is an unusual use case and would
# require a slower implmentation, it's not supported. the
# interpretation of this routine is get_stack_dir for the
# environment this process was launched in.
global _dir_cache_marker
env = os.environ
if stack in _dir_cache:
ros_root = env[ROS_ROOT]
ros_package_path = env.get(ROS_PACKAGE_PATH, '')
if _dir_cache_marker == (ros_root, ros_package_path):
return _dir_cache[stack]
else:
_update_stack_cache() #update cache
# we don't attempt to be thread-safe to environment changes,
# however we do need to be threadsafe to cache invalidation.
try:
if _dir_cache_marker == (ros_root, ros_package_path):
d = _dir_cache[stack]
if os.path.isfile(os.path.join(d, STACK_FILE)):
return d
else:
# invalidate the cache
_dir_cache_marker = None
_dir_cache.clear()
except KeyError:
pass
_update_stack_cache() #update cache
return _dir_cache.get(stack, None)
# rosstack directory cache