Customize ObjectCache for more efficient locking in removeExpiredObjectsInCache

This commit is contained in:
scrawl 2016-02-07 00:43:37 +01:00
parent d855a13b44
commit c155680d3c
5 changed files with 32 additions and 40 deletions

View file

@ -11,13 +11,10 @@
* OpenSceneGraph Public License for more details. * OpenSceneGraph Public License for more details.
*/ */
#include <osg/Version>
#if OSG_VERSION_LESS_THAN(3,3,3)
#include "objectcache.hpp" #include "objectcache.hpp"
using namespace osgDB; namespace Resource
{
//////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////
// //
@ -94,6 +91,9 @@ void ObjectCache::updateTimeStampOfObjectsInCacheWithExternalReferences(double r
} }
void ObjectCache::removeExpiredObjectsInCache(double expiryTime) void ObjectCache::removeExpiredObjectsInCache(double expiryTime)
{
std::vector<osg::ref_ptr<osg::Object> > objectsToRemove;
{ {
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex); OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
@ -103,6 +103,7 @@ void ObjectCache::removeExpiredObjectsInCache(double expiryTime)
{ {
if (oitr->second.second<=expiryTime) if (oitr->second.second<=expiryTime)
{ {
objectsToRemove.push_back(oitr->second.first);
_objectCache.erase(oitr++); _objectCache.erase(oitr++);
} }
else else
@ -112,6 +113,10 @@ void ObjectCache::removeExpiredObjectsInCache(double expiryTime)
} }
} }
// note, actual unref happens outside of the lock
objectsToRemove.clear();
}
void ObjectCache::removeFromObjectCache(const std::string& fileName) void ObjectCache::removeFromObjectCache(const std::string& fileName)
{ {
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex); OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_objectCacheMutex);
@ -138,4 +143,4 @@ void ObjectCache::releaseGLObjects(osg::State* state)
} }
} }
#endif }

View file

@ -1,3 +1,6 @@
// Resource ObjectCache for OpenMW, forked from osgDB ObjectCache by Robert Osfield, see copyright notice below.
// The main change from the upstream version is that removeExpiredObjectsInCache no longer keeps a lock while the unref happens.
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
* *
* This library is open source and may be redistributed and/or modified under * This library is open source and may be redistributed and/or modified under
@ -11,17 +14,8 @@
* OpenSceneGraph Public License for more details. * OpenSceneGraph Public License for more details.
*/ */
// Wrapper for osgDB/ObjectCache. Works around ObjectCache not being available in old OSG 3.2. #ifndef OPENMW_COMPONENTS_RESOURCE_OBJECTCACHE
// Use "#include objectcache.hpp" in place of "#include <osgDB/ObjectCache". #define OPENMW_COMPONENTS_RESOURCE_OBJECTCACHE
#ifndef OSGDB_OBJECTCACHE_WRAPPER
#define OSGDB_OBJECTCACHE_WRAPPER 1
#include <osg/Version>
#if OSG_VERSION_GREATER_OR_EQUAL(3,3,3)
#include <osgDB/ObjectCache>
#else
#include <osg/Node> #include <osg/Node>
@ -30,9 +24,9 @@
#include <map> #include <map>
namespace osgDB { namespace Resource {
class /*OSGDB_EXPORT*/ ObjectCache : public osg::Referenced class ObjectCache : public osg::Referenced
{ {
public: public:
@ -70,7 +64,7 @@ class /*OSGDB_EXPORT*/ ObjectCache : public osg::Referenced
/** Get an ref_ptr<Object> from the object cache*/ /** Get an ref_ptr<Object> from the object cache*/
osg::ref_ptr<osg::Object> getRefFromObjectCache(const std::string& fileName); osg::ref_ptr<osg::Object> getRefFromObjectCache(const std::string& fileName);
/** call rleaseGLObjects on all objects attached to the object cache.*/ /** call releaseGLObjects on all objects attached to the object cache.*/
void releaseGLObjects(osg::State* state); void releaseGLObjects(osg::State* state);
protected: protected:
@ -88,5 +82,3 @@ class /*OSGDB_EXPORT*/ ObjectCache : public osg::Referenced
} }
#endif #endif
#endif

View file

@ -7,7 +7,7 @@ namespace Resource
ResourceManager::ResourceManager(const VFS::Manager *vfs, const double expiryDelay) ResourceManager::ResourceManager(const VFS::Manager *vfs, const double expiryDelay)
: mVFS(vfs) : mVFS(vfs)
, mCache(new osgDB::ObjectCache) , mCache(new Resource::ObjectCache)
, mExpiryDelay(expiryDelay) , mExpiryDelay(expiryDelay)
{ {

View file

@ -8,13 +8,9 @@ namespace VFS
class Manager; class Manager;
} }
namespace osgDB
{
class ObjectCache;
}
namespace Resource namespace Resource
{ {
class ObjectCache;
/// @brief Base class for managers that require a virtual file system and object cache. /// @brief Base class for managers that require a virtual file system and object cache.
/// @par This base class implements clearing of the cache, but populating it and what it's used for is up to the individual sub classes. /// @par This base class implements clearing of the cache, but populating it and what it's used for is up to the individual sub classes.
@ -34,7 +30,7 @@ namespace Resource
protected: protected:
const VFS::Manager* mVFS; const VFS::Manager* mVFS;
osg::ref_ptr<osgDB::ObjectCache> mCache; osg::ref_ptr<Resource::ObjectCache> mCache;
double mExpiryDelay; double mExpiryDelay;
}; };

View file

@ -54,7 +54,6 @@ namespace Resource
void ResourceSystem::updateCache(double referenceTime) void ResourceSystem::updateCache(double referenceTime)
{ {
// TODO: change ObjectCache to not hold lock while the unref happens
for (std::vector<ResourceManager*>::iterator it = mResourceManagers.begin(); it != mResourceManagers.end(); ++it) for (std::vector<ResourceManager*>::iterator it = mResourceManagers.begin(); it != mResourceManagers.end(); ++it)
(*it)->updateCache(referenceTime); (*it)->updateCache(referenceTime);
} }