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_ |