From 2b310c6926a3093880c99186ac1b41916fd73680 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 15 Nov 2004 19:46:10 +0000 Subject: [PATCH] Added support for serialization of calls to ReaderWriter plugins. --- examples/osgarchive/osgarchive.cpp | 4 +-- include/osgDB/Archive | 1 + include/osgDB/ReaderWriter | 40 ++++++++++++++++++++++++ src/osgDB/Registry.cpp | 28 ++++++++--------- src/osgPlugins/net/ReaderWriterNET.cpp | 10 +++--- src/osgPlugins/osga/OSGA_Archive.cpp | 16 +++++----- src/osgPlugins/osga/ReaderWriterOSGA.cpp | 4 +-- src/osgTerrain/DataSet.cpp | 4 +-- 8 files changed, 74 insertions(+), 33 deletions(-) diff --git a/examples/osgarchive/osgarchive.cpp b/examples/osgarchive/osgarchive.cpp index 94b9150be..ebd588b9f 100644 --- a/examples/osgarchive/osgarchive.cpp +++ b/examples/osgarchive/osgarchive.cpp @@ -134,7 +134,7 @@ int main( int argc, char **argv ) if (obj.valid()) { std::cout<<" write to archive "<<*itr<writeObject(*obj, *itr); + archive->threadSafe_writeObject(*obj, *itr); } } } @@ -150,7 +150,7 @@ int main( int argc, char **argv ) ++itr) { osg::Timer_t start = osg::Timer::instance()->tick(); - osgDB::ReaderWriter::ReadResult result = archive->readObject(*itr); + osgDB::ReaderWriter::ReadResult result = archive->threadSafe_readObject(*itr); osg::ref_ptr obj = result.getObject(); std::cout<<"readObejct time = "<delta_m(start,osg::Timer::instance()->tick())< #include +#include + #include +#include namespace osgDB { @@ -160,6 +163,38 @@ class OSGDB_EXPORT ReaderWriter : public osg::Object WRITE, CREATE }; + + #define SERIALIZER() OpenThreads::ScopedLock lock(_serializerMutex) + + + + /** open an archive for reading, writing or or to create an empty archive for writing to.*/ + virtual ReadResult threadSafe_openArchive(const std::string& fileName,ArchiveStatus status, unsigned int indexBlockSize=4096, const Options* options=NULL) { SERIALIZER(); return openArchive(fileName,status, indexBlockSize, options); } + + /** open an archive for reading.*/ + virtual ReadResult threadSafe_openArchive(std::istream& fin,const Options* options=NULL) { SERIALIZER(); return openArchive(fin, options); } + + virtual ReadResult threadSafe_readObject(const std::string& fileName,const Options* options=NULL) { SERIALIZER(); return readObject(fileName,options); } + virtual ReadResult threadSafe_readImage(const std::string& fileName,const Options* options=NULL) { SERIALIZER(); return readImage(fileName,options); } + virtual ReadResult threadSafe_readHeightField(const std::string& fileName,const Options* options=NULL) { SERIALIZER(); return readHeightField(fileName,options); } + virtual ReadResult threadSafe_readNode(const std::string& fileName,const Options* options=NULL) { SERIALIZER(); return readNode(fileName,options); } + + virtual WriteResult threadSafe_writeObject(const osg::Object& obj,const std::string& fileName,const Options* options=NULL) { SERIALIZER(); return writeObject(obj, fileName,options); } + virtual WriteResult threadSafe_writeImage(const osg::Image& image,const std::string& fileName,const Options* options=NULL) { SERIALIZER(); return writeObject(image, fileName,options); } + virtual WriteResult threadSafe_writeHeightField(const osg::HeightField& heightField,const std::string& fileName,const Options* options=NULL) { SERIALIZER(); return writeHeightField(heightField, fileName,options); } + virtual WriteResult threadSafe_writeNode(const osg::Node& node,const std::string& fileName,const Options* options=NULL) { SERIALIZER(); return writeNode(node, fileName,options); } + + virtual ReadResult threadSafe_readObject(std::istream& fin,const Options* options=NULL) { SERIALIZER(); return readObject(fin,options); } + virtual ReadResult threadSafe_readImage(std::istream& fin,const Options* options=NULL) { SERIALIZER(); return readImage(fin,options); } + virtual ReadResult threadSafe_readHeightField(std::istream& fin,const Options* options=NULL) { SERIALIZER(); return readHeightField(fin,options); } + virtual ReadResult threadSafe_readNode(std::istream& fin,const Options* options=NULL) { SERIALIZER(); return readNode(fin,options); } + + virtual WriteResult threadSafe_writeObject(const osg::Object& obj,std::ostream& fout,const Options* options=NULL) { SERIALIZER(); return writeObject(obj, fout, options); } + virtual WriteResult threadSafe_writeImage(const osg::Image& image,std::ostream& fout,const Options* options=NULL) { SERIALIZER(); return writeImage(image, fout, options); } + virtual WriteResult threadSafe_writeHeightField(const osg::HeightField& heightField,std::ostream& fout,const Options* options=NULL) { SERIALIZER(); return writeHeightField(heightField, fout, options); } + virtual WriteResult threadSafe_writeNode(const osg::Node& node,std::ostream& fout,const Options* options=NULL) { SERIALIZER(); return writeNode(node, fout, options); } + + protected: /** open an archive for reading, writing or or to create an empty archive for writing to.*/ virtual ReadResult openArchive(const std::string& /*fileName*/,ArchiveStatus, unsigned int =4096, const Options* =NULL) { return ReadResult(ReadResult::FILE_NOT_HANDLED); } @@ -188,6 +223,11 @@ class OSGDB_EXPORT ReaderWriter : public osg::Object virtual WriteResult writeNode(const osg::Node& /*node*/,std::ostream& /*fout*/,const Options* =NULL) { return WriteResult(WriteResult::FILE_NOT_HANDLED); } + + protected: + + osgDB::ReentrantMutex _serializerMutex; + }; } diff --git a/src/osgDB/Registry.cpp b/src/osgDB/Registry.cpp index 6c59aa794..831ccb24a 100644 --- a/src/osgDB/Registry.cpp +++ b/src/osgDB/Registry.cpp @@ -1122,7 +1122,7 @@ struct Registry::ReadObjectFunctor : public Registry::ReadFunctor { ReadObjectFunctor(const std::string& filename, const ReaderWriter::Options* options):ReadFunctor(filename,options) {} - virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw) const { return rw.readObject(_filename, _options); } + virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw) const { return rw.threadSafe_readObject(_filename, _options); } virtual bool isValid(ReaderWriter::ReadResult& readResult) const { return readResult.validObject(); } virtual bool isValid(osg::Object* object) const { return object!=0; } }; @@ -1131,7 +1131,7 @@ struct Registry::ReadImageFunctor : public Registry::ReadFunctor { ReadImageFunctor(const std::string& filename, const ReaderWriter::Options* options):ReadFunctor(filename,options) {} - virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw)const { return rw.readImage(_filename, _options); } + virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw)const { return rw.threadSafe_readImage(_filename, _options); } virtual bool isValid(ReaderWriter::ReadResult& readResult) const { return readResult.validImage(); } virtual bool isValid(osg::Object* object) const { return dynamic_cast(object)!=0; } }; @@ -1140,7 +1140,7 @@ struct Registry::ReadHeightFieldFunctor : public Registry::ReadFunctor { ReadHeightFieldFunctor(const std::string& filename, const ReaderWriter::Options* options):ReadFunctor(filename,options) {} - virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw) const { return rw.readHeightField(_filename, _options); } + virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw) const { return rw.threadSafe_readHeightField(_filename, _options); } virtual bool isValid(ReaderWriter::ReadResult& readResult) const { return readResult.validHeightField(); } virtual bool isValid(osg::Object* object) const { return dynamic_cast(object)!=0; } }; @@ -1149,7 +1149,7 @@ struct Registry::ReadNodeFunctor : public Registry::ReadFunctor { ReadNodeFunctor(const std::string& filename, const ReaderWriter::Options* options):ReadFunctor(filename,options) {} - virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw) const { return rw.readNode(_filename, _options); } + virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw) const { return rw.threadSafe_readNode(_filename, _options); } virtual bool isValid(ReaderWriter::ReadResult& readResult) const { return readResult.validNode(); } virtual bool isValid(osg::Object* object) const { return dynamic_cast(object)!=0; } @@ -1165,7 +1165,7 @@ struct Registry::ReadArchiveFunctor : public Registry::ReadFunctor ReaderWriter::ArchiveStatus _status; unsigned int _indexBlockSizeHint; - virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw) const { return rw.openArchive(_filename, _status, _indexBlockSizeHint, _options); } + virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw) const { return rw.threadSafe_openArchive(_filename, _status, _indexBlockSizeHint, _options); } virtual bool isValid(ReaderWriter::ReadResult& readResult) const { return readResult.validArchive(); } virtual bool isValid(osg::Object* object) const { return dynamic_cast(object)!=0; } @@ -1194,7 +1194,7 @@ ReaderWriter::ReadResult Registry::read(const ReadFunctor& readFunctor) osg::ref_ptr options = new ReaderWriter::Options; options->setDatabasePath(archiveName); - return archive->readObject(fileName,options.get()); + return archive->threadSafe_readObject(fileName,options.get()); } // if filename contains archive @@ -1392,7 +1392,7 @@ ReaderWriter::WriteResult Registry::writeObjectImplementation(const Object& obj, AvailableReaderWriterIterator itr(_rwList); for(;itr.valid();++itr) { - ReaderWriter::WriteResult rr = itr->writeObject(obj,fileName,_options.get()); + ReaderWriter::WriteResult rr = itr->threadSafe_writeObject(obj,fileName,_options.get()); if (rr.success()) return rr; else results.push_back(rr); } @@ -1403,7 +1403,7 @@ ReaderWriter::WriteResult Registry::writeObjectImplementation(const Object& obj, { for(;itr.valid();++itr) { - ReaderWriter::WriteResult rr = itr->writeObject(obj,fileName,_options.get()); + ReaderWriter::WriteResult rr = itr->threadSafe_writeObject(obj,fileName,_options.get()); if (rr.success()) return rr; else results.push_back(rr); } @@ -1434,7 +1434,7 @@ ReaderWriter::WriteResult Registry::writeImageImplementation(const Image& image, AvailableReaderWriterIterator itr(_rwList); for(;itr.valid();++itr) { - ReaderWriter::WriteResult rr = itr->writeImage(image,fileName,_options.get()); + ReaderWriter::WriteResult rr = itr->threadSafe_writeImage(image,fileName,_options.get()); if (rr.success()) return rr; else results.push_back(rr); } @@ -1445,7 +1445,7 @@ ReaderWriter::WriteResult Registry::writeImageImplementation(const Image& image, { for(;itr.valid();++itr) { - ReaderWriter::WriteResult rr = itr->writeImage(image,fileName,_options.get()); + ReaderWriter::WriteResult rr = itr->threadSafe_writeImage(image,fileName,_options.get()); if (rr.success()) return rr; else results.push_back(rr); } @@ -1475,7 +1475,7 @@ ReaderWriter::WriteResult Registry::writeHeightFieldImplementation(const HeightF AvailableReaderWriterIterator itr(_rwList); for(;itr.valid();++itr) { - ReaderWriter::WriteResult rr = itr->writeHeightField(HeightField,fileName,_options.get()); + ReaderWriter::WriteResult rr = itr->threadSafe_writeHeightField(HeightField,fileName,_options.get()); if (rr.success()) return rr; else results.push_back(rr); } @@ -1486,7 +1486,7 @@ ReaderWriter::WriteResult Registry::writeHeightFieldImplementation(const HeightF { for(;itr.valid();++itr) { - ReaderWriter::WriteResult rr = itr->writeHeightField(HeightField,fileName,_options.get()); + ReaderWriter::WriteResult rr = itr->threadSafe_writeHeightField(HeightField,fileName,_options.get()); if (rr.success()) return rr; else results.push_back(rr); } @@ -1516,7 +1516,7 @@ ReaderWriter::WriteResult Registry::writeNodeImplementation(const Node& node,con AvailableReaderWriterIterator itr(_rwList); for(;itr.valid();++itr) { - ReaderWriter::WriteResult rr = itr->writeNode(node,fileName,_options.get()); + ReaderWriter::WriteResult rr = itr->threadSafe_writeNode(node,fileName,_options.get()); if (rr.success()) return rr; else results.push_back(rr); } @@ -1527,7 +1527,7 @@ ReaderWriter::WriteResult Registry::writeNodeImplementation(const Node& node,con { for(;itr.valid();++itr) { - ReaderWriter::WriteResult rr = itr->writeNode(node,fileName,_options.get()); + ReaderWriter::WriteResult rr = itr->threadSafe_writeNode(node,fileName,_options.get()); if (rr.success()) return rr; else results.push_back(rr); } diff --git a/src/osgPlugins/net/ReaderWriterNET.cpp b/src/osgPlugins/net/ReaderWriterNET.cpp index 973919f36..477c46ae8 100644 --- a/src/osgPlugins/net/ReaderWriterNET.cpp +++ b/src/osgPlugins/net/ReaderWriterNET.cpp @@ -122,11 +122,11 @@ class NetReader : public osgDB::ReaderWriter { switch(objectType) { - case(OBJECT): return rw->readObject(fin,options); - case(ARCHIVE): return rw->openArchive(fin,options); - case(IMAGE): return rw->readImage(fin,options); - case(HEIGHTFIELD): return rw->readHeightField(fin,options); - case(NODE): return rw->readNode(fin,options); + case(OBJECT): return rw->threadSafe_readObject(fin,options); + case(ARCHIVE): return rw->threadSafe_openArchive(fin,options); + case(IMAGE): return rw->threadSafe_readImage(fin,options); + case(HEIGHTFIELD): return rw->threadSafe_readHeightField(fin,options); + case(NODE): return rw->threadSafe_readNode(fin,options); default: break; } return ReadResult::FILE_NOT_HANDLED; diff --git a/src/osgPlugins/osga/OSGA_Archive.cpp b/src/osgPlugins/osga/OSGA_Archive.cpp index d7dedcb3c..c914fb88a 100644 --- a/src/osgPlugins/osga/OSGA_Archive.cpp +++ b/src/osgPlugins/osga/OSGA_Archive.cpp @@ -507,25 +507,25 @@ class proxy_streambuf : public std::streambuf struct OSGA_Archive::ReadObjectFunctor : public OSGA_Archive::ReadFunctor { ReadObjectFunctor(const std::string& filename, const ReaderWriter::Options* options):ReadFunctor(filename,options) {} - virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw, std::istream& input) const { return rw.readObject(input, _options); } + virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw, std::istream& input) const { return rw.threadSafe_readObject(input, _options); } }; struct OSGA_Archive::ReadImageFunctor : public OSGA_Archive::ReadFunctor { ReadImageFunctor(const std::string& filename, const ReaderWriter::Options* options):ReadFunctor(filename,options) {} - virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw, std::istream& input)const { return rw.readImage(input, _options); } + virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw, std::istream& input)const { return rw.threadSafe_readImage(input, _options); } }; struct OSGA_Archive::ReadHeightFieldFunctor : public OSGA_Archive::ReadFunctor { ReadHeightFieldFunctor(const std::string& filename, const ReaderWriter::Options* options):ReadFunctor(filename,options) {} - virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw, std::istream& input) const { return rw.readHeightField(input, _options); } + virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw, std::istream& input) const { return rw.threadSafe_readHeightField(input, _options); } }; struct OSGA_Archive::ReadNodeFunctor : public OSGA_Archive::ReadFunctor { ReadNodeFunctor(const std::string& filename, const ReaderWriter::Options* options):ReadFunctor(filename,options) {} - virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw, std::istream& input) const { return rw.readNode(input, _options); } + virtual ReaderWriter::ReadResult doRead(ReaderWriter& rw, std::istream& input) const { return rw.threadSafe_readNode(input, _options); } }; ReaderWriter::ReadResult OSGA_Archive::read(const ReadFunctor& readFunctor) @@ -594,7 +594,7 @@ struct OSGA_Archive::WriteObjectFunctor : public OSGA_Archive::WriteFunctor _object(object) {} const osg::Object& _object; - virtual ReaderWriter::WriteResult doWrite(ReaderWriter& rw, std::ostream& output) const { return rw.writeObject(_object, output, _options); } + virtual ReaderWriter::WriteResult doWrite(ReaderWriter& rw, std::ostream& output) const { return rw.threadSafe_writeObject(_object, output, _options); } }; struct OSGA_Archive::WriteImageFunctor : public OSGA_Archive::WriteFunctor @@ -604,7 +604,7 @@ struct OSGA_Archive::WriteImageFunctor : public OSGA_Archive::WriteFunctor _object(object) {} const osg::Image& _object; - virtual ReaderWriter::WriteResult doWrite(ReaderWriter& rw, std::ostream& output)const { return rw.writeImage(_object, output, _options); } + virtual ReaderWriter::WriteResult doWrite(ReaderWriter& rw, std::ostream& output)const { return rw.threadSafe_writeImage(_object, output, _options); } }; struct OSGA_Archive::WriteHeightFieldFunctor : public OSGA_Archive::WriteFunctor @@ -614,7 +614,7 @@ struct OSGA_Archive::WriteHeightFieldFunctor : public OSGA_Archive::WriteFunctor _object(object) {} const osg::HeightField& _object; - virtual ReaderWriter::WriteResult doWrite(ReaderWriter& rw, std::ostream& output) const { return rw.writeHeightField(_object, output, _options); } + virtual ReaderWriter::WriteResult doWrite(ReaderWriter& rw, std::ostream& output) const { return rw.threadSafe_writeHeightField(_object, output, _options); } }; struct OSGA_Archive::WriteNodeFunctor : public OSGA_Archive::WriteFunctor @@ -624,7 +624,7 @@ struct OSGA_Archive::WriteNodeFunctor : public OSGA_Archive::WriteFunctor _object(object) {} const osg::Node& _object; - virtual ReaderWriter::WriteResult doWrite(ReaderWriter& rw, std::ostream& output) const { return rw.writeNode(_object, output, _options); } + virtual ReaderWriter::WriteResult doWrite(ReaderWriter& rw, std::ostream& output) const { return rw.threadSafe_writeNode(_object, output, _options); } }; ReaderWriter::WriteResult OSGA_Archive::write(const WriteFunctor& writeFunctor) diff --git a/src/osgPlugins/osga/ReaderWriterOSGA.cpp b/src/osgPlugins/osga/ReaderWriterOSGA.cpp index b0023e9e4..28ad20942 100644 --- a/src/osgPlugins/osga/ReaderWriterOSGA.cpp +++ b/src/osgPlugins/osga/ReaderWriterOSGA.cpp @@ -61,7 +61,7 @@ public: osg::ref_ptr local_options = new ReaderWriter::Options; local_options->setDatabasePath(file); - ReadResult result_2 = result.getArchive()->readImage(result.getArchive()->getMasterFileName(),local_options.get()); + ReadResult result_2 = result.getArchive()->threadSafe_readImage(result.getArchive()->getMasterFileName(),local_options.get()); // register the archive so that it is cached for future use. @@ -81,7 +81,7 @@ public: osg::ref_ptr local_options = new ReaderWriter::Options; local_options->setDatabasePath(file); - ReadResult result_2 = result.getArchive()->readNode(result.getArchive()->getMasterFileName(),local_options.get()); + ReadResult result_2 = result.getArchive()->threadSafe_readNode(result.getArchive()->getMasterFileName(),local_options.get()); // register the archive so that it is cached for future use. diff --git a/src/osgTerrain/DataSet.cpp b/src/osgTerrain/DataSet.cpp index 5483abad4..20c17e601 100644 --- a/src/osgTerrain/DataSet.cpp +++ b/src/osgTerrain/DataSet.cpp @@ -3724,13 +3724,13 @@ void DataSet::_equalizeRow(Row& row) void DataSet::_writeNodeFile(const osg::Node& node,const std::string& filename) { - if (_archive.valid()) _archive->writeNode(node,filename); + if (_archive.valid()) _archive->threadSafe_writeNode(node,filename); else osgDB::writeNodeFile(node, filename); } void DataSet::_writeImageFile(const osg::Image& image,const std::string& filename) { - if (_archive.valid()) _archive->writeImage(image,filename); + if (_archive.valid()) _archive->threadSafe_writeImage(image,filename); else osgDB::writeImageFile(image, filename); }