| Index: webkit/fileapi/isolated_context.cc
|
| diff --git a/webkit/fileapi/isolated_context.cc b/webkit/fileapi/isolated_context.cc
|
| index 8eac660bdf5582fda8fa2f1b54c9fbf8277c645d..957680d06f3b7701d55e88a25a31b6399bc8540a 100644
|
| --- a/webkit/fileapi/isolated_context.cc
|
| +++ b/webkit/fileapi/isolated_context.cc
|
| @@ -39,6 +39,31 @@ FilePath::StringType GetRegisterNameForPath(const FilePath& path) {
|
| #endif
|
| }
|
|
|
| +bool IsSinglePathIsolatedFileSystem(FileSystemType type) {
|
| + switch (type) {
|
| + // As of writing dragged file system is the only filesystem
|
| + // which could have multiple toplevel paths.
|
| + case kFileSystemTypeDragged:
|
| + return false;
|
| +
|
| + // Regular file systems.
|
| + case kFileSystemTypeIsolated:
|
| + case kFileSystemTypeNativeMedia:
|
| + case kFileSystemTypeDeviceMedia:
|
| + case kFileSystemTypeTemporary:
|
| + case kFileSystemTypePersistent:
|
| + case kFileSystemTypeExternal:
|
| + case kFileSystemTypeTest:
|
| + return true;
|
| +
|
| + case kFileSystemTypeUnknown:
|
| + NOTREACHED();
|
| + return true;
|
| + }
|
| + NOTREACHED();
|
| + return true;
|
| +}
|
| +
|
| }
|
|
|
| static base::LazyInstance<IsolatedContext>::Leaky g_isolated_context =
|
| @@ -91,29 +116,38 @@ IsolatedContext::Instance::Instance(FileSystemType type,
|
| const FileInfo& file_info)
|
| : type_(type),
|
| file_info_(file_info),
|
| - ref_counts_(0) {}
|
| + ref_counts_(0) {
|
| + DCHECK(IsSinglePathIsolatedFileSystem(type_));
|
| +}
|
|
|
| -IsolatedContext::Instance::Instance(const std::set<FileInfo>& dragged_files)
|
| - : type_(kFileSystemTypeDragged),
|
| - dragged_files_(dragged_files),
|
| - ref_counts_(0) {}
|
| +IsolatedContext::Instance::Instance(FileSystemType type,
|
| + const std::set<FileInfo>& files)
|
| + : type_(type),
|
| + files_(files),
|
| + ref_counts_(0) {
|
| + DCHECK(!IsSinglePathIsolatedFileSystem(type_));
|
| +}
|
|
|
| IsolatedContext::Instance::~Instance() {}
|
|
|
| bool IsolatedContext::Instance::ResolvePathForName(const std::string& name,
|
| - FilePath* path) {
|
| - if (type_ != kFileSystemTypeDragged) {
|
| + FilePath* path) const {
|
| + if (IsSinglePathIsolatedFileSystem(type_)) {
|
| *path = file_info_.path;
|
| return file_info_.name == name;
|
| }
|
| - std::set<FileInfo>::const_iterator found = dragged_files_.find(
|
| + std::set<FileInfo>::const_iterator found = files_.find(
|
| FileInfo(name, FilePath()));
|
| - if (found == dragged_files_.end())
|
| + if (found == files_.end())
|
| return false;
|
| *path = found->path;
|
| return true;
|
| }
|
|
|
| +bool IsolatedContext::Instance::IsSinglePathInstance() const {
|
| + return IsSinglePathIsolatedFileSystem(type_);
|
| +}
|
| +
|
| //--------------------------------------------------------------------------
|
|
|
| // static
|
| @@ -125,7 +159,8 @@ std::string IsolatedContext::RegisterDraggedFileSystem(
|
| const FileInfoSet& files) {
|
| base::AutoLock locker(lock_);
|
| std::string filesystem_id = GetNewFileSystemId();
|
| - instance_map_[filesystem_id] = new Instance(files.fileset());
|
| + instance_map_[filesystem_id] = new Instance(
|
| + kFileSystemTypeDragged, files.fileset());
|
| return filesystem_id;
|
| }
|
|
|
| @@ -146,16 +181,25 @@ std::string IsolatedContext::RegisterFileSystemForPath(
|
| base::AutoLock locker(lock_);
|
| std::string filesystem_id = GetNewFileSystemId();
|
| instance_map_[filesystem_id] = new Instance(type, FileInfo(name, path));
|
| + path_to_id_map_[path].insert(filesystem_id);
|
| return filesystem_id;
|
| }
|
|
|
| -void IsolatedContext::RevokeFileSystem(const std::string& filesystem_id) {
|
| +void IsolatedContext::RevokeFileSystemByPath(const FilePath& path) {
|
| base::AutoLock locker(lock_);
|
| - IDToInstance::iterator found = instance_map_.find(filesystem_id);
|
| - if (found == instance_map_.end())
|
| + PathToID::iterator ids_iter = path_to_id_map_.find(path);
|
| + if (ids_iter == path_to_id_map_.end())
|
| return;
|
| - delete found->second;
|
| - instance_map_.erase(found);
|
| + std::set<std::string>& ids = ids_iter->second;
|
| + for (std::set<std::string>::iterator iter = ids.begin();
|
| + iter != ids.end(); ++iter) {
|
| + IDToInstance::iterator found = instance_map_.find(*iter);
|
| + if (found != instance_map_.end()) {
|
| + delete found->second;
|
| + instance_map_.erase(found);
|
| + }
|
| + }
|
| + path_to_id_map_.erase(ids_iter);
|
| }
|
|
|
| void IsolatedContext::AddReference(const std::string& filesystem_id) {
|
| @@ -167,14 +211,23 @@ void IsolatedContext::AddReference(const std::string& filesystem_id) {
|
| void IsolatedContext::RemoveReference(const std::string& filesystem_id) {
|
| base::AutoLock locker(lock_);
|
| // This could get called for non-existent filesystem if it has been
|
| - // already deleted by RevokeFileSystem.
|
| + // already deleted by RevokeFileSystemByPath.
|
| IDToInstance::iterator found = instance_map_.find(filesystem_id);
|
| if (found == instance_map_.end())
|
| return;
|
| - DCHECK(found->second->ref_counts() > 0);
|
| - found->second->RemoveRef();
|
| - if (found->second->ref_counts() == 0) {
|
| - delete found->second;
|
| + Instance* instance = found->second;
|
| + DCHECK(instance->ref_counts() > 0);
|
| + instance->RemoveRef();
|
| + if (instance->ref_counts() == 0) {
|
| + if (instance->IsSinglePathInstance()) {
|
| + PathToID::iterator ids_iter = path_to_id_map_.find(
|
| + instance->file_info().path);
|
| + DCHECK(ids_iter != path_to_id_map_.end());
|
| + ids_iter->second.erase(filesystem_id);
|
| + if (ids_iter->second.empty())
|
| + path_to_id_map_.erase(ids_iter);
|
| + }
|
| + delete instance;
|
| instance_map_.erase(found);
|
| }
|
| }
|
| @@ -229,8 +282,8 @@ bool IsolatedContext::GetDraggedFileInfo(
|
| if (found == instance_map_.end() ||
|
| found->second->type() != kFileSystemTypeDragged)
|
| return false;
|
| - files->assign(found->second->dragged_files().begin(),
|
| - found->second->dragged_files().end());
|
| + files->assign(found->second->files().begin(),
|
| + found->second->files().end());
|
| return true;
|
| }
|
|
|
| @@ -239,8 +292,7 @@ bool IsolatedContext::GetRegisteredPath(
|
| DCHECK(path);
|
| base::AutoLock locker(lock_);
|
| IDToInstance::const_iterator found = instance_map_.find(filesystem_id);
|
| - if (found == instance_map_.end() ||
|
| - found->second->type() == kFileSystemTypeDragged)
|
| + if (found == instance_map_.end() || !found->second->IsSinglePathInstance())
|
| return false;
|
| *path = found->second->file_info().path;
|
| return true;
|
|
|