Chromium Code Reviews| Index: components/leveldb/leveldb_mojo_proxy.h |
| diff --git a/components/leveldb/leveldb_mojo_proxy.h b/components/leveldb/leveldb_mojo_proxy.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..d180d2feba001ff2b475b0ea1b4a6211ecde231f |
| --- /dev/null |
| +++ b/components/leveldb/leveldb_mojo_proxy.h |
| @@ -0,0 +1,168 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#ifndef COMPONENTS_LEVELDB_LEVELDB_MOJO_PROXY_H_ |
| +#define COMPONENTS_LEVELDB_LEVELDB_MOJO_PROXY_H_ |
| + |
| +#include <map> |
| +#include <string> |
| +#include <utility> |
| +#include <vector> |
| + |
| +#include "base/files/file.h" |
| +#include "base/memory/ref_counted.h" |
| +#include "base/synchronization/waitable_event.h" |
| +#include "base/threading/thread.h" |
| +#include "components/filesystem/public/interfaces/directory.mojom.h" |
| + |
| +namespace leveldb { |
| + |
| +// A proxy for thread safe access to mojo objects from multiple threads. |
| +// |
| +// MojoEnv is an object passed to the leveldb implementation which can be |
|
jam
2016/03/29 05:58:00
nit: just to be consistent with how these projects
|
| +// called from multiple threads. mojo pipes are bound to a single |
| +// thread. Because of this mismatch, we create a proxy object which will |
| +// redirect calls to the thread which owns the mojo pipe, sends and receives |
| +// messages. |
| +// |
| +// All public methods can be accessed from any thread. |
| +class LevelDBMojoProxy : public base::RefCountedThreadSafe<LevelDBMojoProxy> { |
| + public: |
| + explicit LevelDBMojoProxy( |
| + scoped_refptr<base::SingleThreadTaskRunner> task_runner); |
| + |
| + // A private struct to hide the underlying file that holds the lock from our |
| + // callers, forcing them to go through our LockFile()/UnlockFile() interface |
| + // so that they don't try to use the underlying pointer from an unsafe thread. |
| + struct OpaqueLock; |
| + |
| + // A private struct to hide the underlying root directory that we're |
| + // operating in. LevelDBMojoProxy will want to own all the directory |
| + // pointers, so while opening a database, we pass the directory to the thread |
| + // it will be operated on. |
| + struct OpaqueDir; |
| + |
| + // Passes ownership of a |directory| to the other thread, giving a reference |
| + // handle back to the caller. |
| + OpaqueDir* RegisterDirectory(filesystem::DirectoryPtr directory); |
| + void UnregisterDirectory(OpaqueDir* dir); |
| + |
| + // Synchronously calls Directory.OpenFileHandle(). |
| + base::File OpenFileHandle(OpaqueDir* dir, |
| + const std::string& name, |
| + uint32_t open_flags); |
| + |
| + // Synchronously flushes |directory_|. |
|
jam
2016/03/29 05:58:00
nit: s/flushes/sync
|
| + filesystem::FileError SyncDirectory(OpaqueDir* dir, const std::string& name); |
| + |
| + // Synchronously checks whether |name| exists. |
| + bool FileExists(OpaqueDir* dir, const std::string& name); |
| + |
| + // Synchronously returns the filenames of all files in |path|. |
| + filesystem::FileError GetChildren(OpaqueDir* dir, |
| + const std::string& path, |
| + std::vector<std::string>* result); |
| + |
| + // Synchronously deletes |path|. |
| + filesystem::FileError Delete(OpaqueDir* dir, |
| + const std::string& path, |
| + uint32_t delete_flags); |
| + |
| + // Synchronously creates |path|. |
| + filesystem::FileError CreateDir(OpaqueDir* dir, const std::string& path); |
| + |
| + // Synchronously gets the size of a file. |
| + filesystem::FileError GetFileSize(OpaqueDir* dir, |
| + const std::string& path, |
| + uint64_t* file_size); |
| + |
| + // Synchronously renames a file. |
| + filesystem::FileError RenameFile(OpaqueDir* dir, |
| + const std::string& old_path, |
| + const std::string& new_path); |
| + |
| + // Synchronously locks a file. Returns both the file return code, and if OK, |
| + // an opaque object to the lock to enforce going through this interface to |
| + // unlock the file so that unlocking happens on the correct thread. |
| + std::pair<filesystem::FileError, OpaqueLock*> LockFile( |
| + OpaqueDir* dir, |
| + const std::string& path); |
| + |
| + // Unlocks a file. LevelDBMojoProxy takes ownership of lock. (We don't make |
| + // this a scoped_ptr because exporting the ctor/dtor for this struct publicly |
| + // defeats the purpose of the struct.) |
| + filesystem::FileError UnlockFile(OpaqueLock* lock); |
| + |
| + private: |
| + friend class base::RefCountedThreadSafe<LevelDBMojoProxy>; |
| + ~LevelDBMojoProxy(); |
| + |
| + void SignalIfNeeded(base::WaitableEvent* done_event); |
| + |
| + // Implementation methods of the public interface. Depending on whether they |
| + // were called from the thread that |task_runner_| is, these might be called |
| + // directly or through PostTask(). |
| + void RegisterDirectoryImpl( |
| + mojo::InterfacePtrInfo<filesystem::Directory> directory_info, |
| + base::WaitableEvent* done_event, |
| + OpaqueDir** out_dir); |
| + void UnregisterDirectoryImpl(OpaqueDir* dir, base::WaitableEvent* done_event); |
| + void OpenFileHandleImpl(OpaqueDir* dir, |
| + std::string name, |
| + uint32_t open_flags, |
| + base::WaitableEvent* done_event, |
| + base::File* out_file); |
| + void SyncDirectoryImpl(OpaqueDir* dir, |
| + std::string name, |
| + base::WaitableEvent* done_event, |
| + filesystem::FileError* out_error); |
| + void FileExistsImpl(OpaqueDir* dir, |
| + std::string name, |
| + base::WaitableEvent* done_event, |
| + bool* exists); |
| + void GetChildrenImpl(OpaqueDir* dir, |
| + std::string name, |
| + std::vector<std::string>* contents, |
| + base::WaitableEvent* done_event, |
| + filesystem::FileError* out_error); |
| + void DeleteImpl(OpaqueDir* dir, |
| + std::string name, |
| + uint32_t delete_flags, |
| + base::WaitableEvent* done_event, |
| + filesystem::FileError* out_error); |
| + void CreateDirImpl(OpaqueDir* dir, |
| + std::string name, |
| + base::WaitableEvent* done_event, |
| + filesystem::FileError* out_error); |
| + void GetFileSizeImpl(OpaqueDir* dir, |
| + const std::string& path, |
| + uint64_t* file_size, |
| + base::WaitableEvent* done_event, |
| + filesystem::FileError* out_error); |
| + void RenameFileImpl(OpaqueDir* dir, |
| + const std::string& old_path, |
| + const std::string& new_path, |
| + base::WaitableEvent* done_event, |
| + filesystem::FileError* out_error); |
| + void LockFileImpl(OpaqueDir* dir, |
| + const std::string& path, |
| + base::WaitableEvent* done_event, |
| + filesystem::FileError* out_error, |
| + OpaqueLock** out_lock); |
| + void UnlockFileImpl(scoped_ptr<OpaqueLock> lock, |
| + base::WaitableEvent* done_event, |
| + filesystem::FileError* out_error); |
| + |
| + // The task runner which represents the thread that all mojo objects are |
| + // bound to. |
| + scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| + |
| + int outstanding_opaque_dirs_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(LevelDBMojoProxy); |
| +}; |
| + |
| +} // namespace leveldb |
| + |
| +#endif // COMPONENTS_LEVELDB_LEVELDB_MOJO_PROXY_H_ |