Fix a race condition in directory_watcher_inotify.cc: release lock before signaling the event dtor waits on.

http://crbug.com/15055
Review URL: http://codereview.chromium.org/147052

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@19151 0039d316-1c4b-4281-b951-d872f2087c98
Esse commit está contido em:
phajdan.jr@chromium.org
2009-06-24 18:43:44 +00:00
commit 4d07728a49
+24 -16
Ver Arquivo
@@ -397,24 +397,32 @@ bool DirectoryWatcherImpl::OnEnumeratedSubtree(const FilePathSet& subtree) {
}
bool success = true;
AutoLock auto_lock(lock_);
for (FilePathSet::iterator subdirectory = subtree.begin();
subdirectory != subtree.end();
++subdirectory) {
ino_t inode;
if (!file_util::GetInode(*subdirectory, &inode)) {
success = false;
continue;
}
if (IsInodeWatched(inode))
continue;
InotifyReader::Watch watch =
Singleton<InotifyReader>::get()->AddWatch(*subdirectory, this);
if (watch != InotifyReader::kInvalidWatch) {
watches_.insert(watch);
inodes_watched_.insert(inode);
{
// Limit the scope of auto_lock so it releases lock_ before we signal
// recursive_setup_finished_. Our dtor waits on recursive_setup_finished_
// and could otherwise destroy the lock before we release it.
AutoLock auto_lock(lock_);
for (FilePathSet::iterator subdirectory = subtree.begin();
subdirectory != subtree.end();
++subdirectory) {
ino_t inode;
if (!file_util::GetInode(*subdirectory, &inode)) {
success = false;
continue;
}
if (IsInodeWatched(inode))
continue;
InotifyReader::Watch watch =
Singleton<InotifyReader>::get()->AddWatch(*subdirectory, this);
if (watch != InotifyReader::kInvalidWatch) {
watches_.insert(watch);
inodes_watched_.insert(inode);
}
}
}
recursive_setup_finished_.Signal();
return success;
}