fixed some mutex bugs and some pointer access bugs in the FileIndexStore

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@1525 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2009-08-12 22:06:11 +00:00
parent caf1c7850f
commit 243af3ffee
3 changed files with 40 additions and 16 deletions

View File

@ -34,18 +34,31 @@
#include <fstream> #include <fstream>
#include <openssl/sha.h> #include <openssl/sha.h>
#include <util/rsthreads.h>
/**** /****
#define FI_DEBUG 1 #define FI_DEBUG 1
* #define FI_DEBUG_ALL 1 * #define FI_DEBUG_ALL 1
****/ ****/
static std::set<void*> _pointers ; static RsMutex FIndexPtrMtx ;
static void registerEntry(void*p) { _pointers.insert(p) ; } std::set<void*> FileIndex::_pointers ;
static void unregisterEntry(void*p)
void FileIndex::registerEntry(void*p)
{ {
RsStackMutex m(FIndexPtrMtx) ;
_pointers.insert(p) ;
}
void FileIndex::unregisterEntry(void*p)
{
RsStackMutex m(FIndexPtrMtx) ;
_pointers.erase(p) ; _pointers.erase(p) ;
} }
bool FileIndex::isValid(void*p)
{
RsStackMutex m(FIndexPtrMtx) ;
return _pointers.find(p) != _pointers.end() ;
}
DirEntry::~DirEntry() DirEntry::~DirEntry()
{ {
@ -55,14 +68,14 @@ DirEntry::~DirEntry()
for(dit = subdirs.begin(); dit != subdirs.end(); dit++) for(dit = subdirs.begin(); dit != subdirs.end(); dit++)
{ {
unregisterEntry((void*)dit->second) ; FileIndex::unregisterEntry((void*)dit->second) ;
delete (dit->second); delete (dit->second);
} }
subdirs.clear(); subdirs.clear();
for(fit = files.begin(); fit != files.end(); fit++) for(fit = files.begin(); fit != files.end(); fit++)
{ {
unregisterEntry((void*)fit->second) ; FileIndex::unregisterEntry((void*)fit->second) ;
delete (fit->second); delete (fit->second);
} }
files.clear(); files.clear();
@ -138,7 +151,7 @@ int DirEntry::removeDir(std::string name)
ndir = (it->second); ndir = (it->second);
subdirs.erase(it); subdirs.erase(it);
unregisterEntry((void*)ndir) ; FileIndex::unregisterEntry((void*)ndir) ;
delete ndir; delete ndir;
/* update row counters */ /* update row counters */
updateChildRows(); updateChildRows();
@ -168,7 +181,7 @@ int DirEntry::removeFile(std::string name)
nfile = (it->second); nfile = (it->second);
files.erase(it); files.erase(it);
unregisterEntry((void*)nfile) ; FileIndex::unregisterEntry((void*)nfile) ;
delete nfile; delete nfile;
/* update row counters */ /* update row counters */
updateChildRows(); updateChildRows();
@ -199,7 +212,7 @@ int DirEntry::removeOldDir(std::string name, time_t old)
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
subdirs.erase(it); subdirs.erase(it);
unregisterEntry((void*)ndir) ; FileIndex::unregisterEntry((void*)ndir) ;
delete ndir; delete ndir;
/* update row counters */ /* update row counters */
@ -375,7 +388,7 @@ DirEntry *DirEntry::updateDir(FileEntry fe, time_t utime)
std::cerr << std::endl; std::cerr << std::endl;
#endif #endif
ndir = new DirEntry(); ndir = new DirEntry();
registerEntry((void*)ndir) ; FileIndex::registerEntry((void*)ndir) ;
ndir -> parent = this; ndir -> parent = this;
ndir -> path = path + "/" + fe.name; ndir -> path = path + "/" + fe.name;
ndir -> name = fe.name; ndir -> name = fe.name;
@ -417,7 +430,7 @@ FileEntry *DirEntry::updateFile(FileEntry fe, time_t utime)
#endif #endif
nfile = new FileEntry(); nfile = new FileEntry();
registerEntry((void*)nfile) ; FileIndex::registerEntry((void*)nfile) ;
nfile -> parent = this; nfile -> parent = this;
nfile -> name = fe.name; nfile -> name = fe.name;
nfile -> hash = fe.hash; nfile -> hash = fe.hash;
@ -504,7 +517,7 @@ FileIndex::FileIndex(std::string pid)
FileIndex::~FileIndex() FileIndex::~FileIndex()
{ {
unregisterEntry((void*)root) ; FileIndex::unregisterEntry((void*)root) ;
delete root; delete root;
} }
@ -750,7 +763,7 @@ int FileIndex::loadIndex(std::string filename, std::string expectedHash, uint64_
case 1: case 1:
{ {
std::string pid = root -> id; std::string pid = root -> id;
unregisterEntry((void*)root) ; FileIndex::unregisterEntry((void*)root) ;
delete root; /* to clean up old entries */ delete root; /* to clean up old entries */
root = new PersonEntry(pid); root = new PersonEntry(pid);
registerEntry((void*)root) ; registerEntry((void*)root) ;
@ -763,7 +776,7 @@ int FileIndex::loadIndex(std::string filename, std::string expectedHash, uint64_
/* now cleanup (can't call standard delete) */ /* now cleanup (can't call standard delete) */
ndir->subdirs.clear(); ndir->subdirs.clear();
ndir->files.clear(); ndir->files.clear();
unregisterEntry((void*)ndir) ; FileIndex::unregisterEntry((void*)ndir) ;
delete ndir; delete ndir;
ndir = NULL; ndir = NULL;
@ -1134,7 +1147,7 @@ int FileIndex::RequestDirDetails(void *ref, DirDetails &details, uint32_t flags)
{ {
/* so cast *ref to a DirEntry */ /* so cast *ref to a DirEntry */
if(ref != NULL && _pointers.find(ref) == _pointers.end()) if(ref != NULL && !isValid(ref))
return false ; return false ;
FileEntry *file = (FileEntry *) ref; FileEntry *file = (FileEntry *) ref;

View File

@ -229,6 +229,11 @@ class FileIndex
/* browse thru directories */ /* browse thru directories */
int RequestDirDetails(void *ref, DirDetails &details, uint32_t flags) const; int RequestDirDetails(void *ref, DirDetails &details, uint32_t flags) const;
PersonEntry *root; PersonEntry *root;
static std::set<void*> _pointers ;
static void registerEntry(void*p) ;
static void unregisterEntry(void*p) ;
static bool isValid(void*p) ;
}; };

View File

@ -166,8 +166,6 @@ int FileIndexStore::RequestDirDetails(std::string uid, std::string path, DirDeta
int FileIndexStore::RequestDirDetails(void *ref, DirDetails &details, uint32_t flags) const int FileIndexStore::RequestDirDetails(void *ref, DirDetails &details, uint32_t flags) const
{ {
lockData();
#ifdef FIS_DEBUG #ifdef FIS_DEBUG
std::cerr << "FileIndexStore::RequestDirDetails() ref=" << ref << " flags: " << flags << std::endl; std::cerr << "FileIndexStore::RequestDirDetails() ref=" << ref << " flags: " << flags << std::endl;
#endif #endif
@ -175,6 +173,14 @@ int FileIndexStore::RequestDirDetails(void *ref, DirDetails &details, uint32_t f
bool found = true; bool found = true;
std::map<RsPeerId, FileIndex *>::const_iterator pit; std::map<RsPeerId, FileIndex *>::const_iterator pit;
lockData();
if(ref != NULL && !FileIndex::isValid(ref))
{
unlockData() ;
return false ;
}
/* so cast *ref to a DirEntry */ /* so cast *ref to a DirEntry */
FileEntry *file = (FileEntry *) ref; FileEntry *file = (FileEntry *) ref;
DirEntry *dir = dynamic_cast<DirEntry *>(file); DirEntry *dir = dynamic_cast<DirEntry *>(file);