OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #ifndef COMPONENTS_LEVELDB_LEVELDB_MOJO_PROXY_H_ |
| 6 #define COMPONENTS_LEVELDB_LEVELDB_MOJO_PROXY_H_ |
| 7 |
| 8 #include <map> |
| 9 #include <string> |
| 10 #include <utility> |
| 11 #include <vector> |
| 12 |
| 13 #include "base/callback_forward.h" |
| 14 #include "base/files/file.h" |
| 15 #include "base/memory/ref_counted.h" |
| 16 #include "base/synchronization/waitable_event.h" |
| 17 #include "base/threading/thread.h" |
| 18 #include "components/filesystem/public/interfaces/directory.mojom.h" |
| 19 |
| 20 namespace leveldb { |
| 21 |
| 22 // A proxy for thread safe access to Mojo objects from multiple threads. |
| 23 // |
| 24 // MojoEnv is an object passed to the LevelDB implementation which can be |
| 25 // called from multiple threads. Mojo pipes are bound to a single |
| 26 // thread. Because of this mismatch, we create a proxy object which will |
| 27 // redirect calls to the thread which owns the Mojo pipe, sends and receives |
| 28 // messages. |
| 29 // |
| 30 // All public methods can be accessed from any thread. |
| 31 class LevelDBMojoProxy : public base::RefCountedThreadSafe<LevelDBMojoProxy> { |
| 32 public: |
| 33 explicit LevelDBMojoProxy( |
| 34 scoped_refptr<base::SingleThreadTaskRunner> task_runner); |
| 35 |
| 36 // A private struct to hide the underlying file that holds the lock from our |
| 37 // callers, forcing them to go through our LockFile()/UnlockFile() interface |
| 38 // so that they don't try to use the underlying pointer from an unsafe thread. |
| 39 struct OpaqueLock; |
| 40 |
| 41 // A private struct to hide the underlying root directory that we're |
| 42 // operating in. LevelDBMojoProxy will want to own all the directory |
| 43 // pointers, so while opening a database, we pass the directory to the thread |
| 44 // it will be operated on. |
| 45 struct OpaqueDir; |
| 46 |
| 47 // Passes ownership of a |directory| to the other thread, giving a reference |
| 48 // handle back to the caller. |
| 49 OpaqueDir* RegisterDirectory(filesystem::DirectoryPtr directory); |
| 50 void UnregisterDirectory(OpaqueDir* dir); |
| 51 |
| 52 // Synchronously calls Directory.OpenFileHandle(). |
| 53 base::File OpenFileHandle(OpaqueDir* dir, |
| 54 const std::string& name, |
| 55 uint32_t open_flags); |
| 56 |
| 57 // Synchronously syncs |directory_|. |
| 58 filesystem::FileError SyncDirectory(OpaqueDir* dir, const std::string& name); |
| 59 |
| 60 // Synchronously checks whether |name| exists. |
| 61 bool FileExists(OpaqueDir* dir, const std::string& name); |
| 62 |
| 63 // Synchronously returns the filenames of all files in |path|. |
| 64 filesystem::FileError GetChildren(OpaqueDir* dir, |
| 65 const std::string& path, |
| 66 std::vector<std::string>* result); |
| 67 |
| 68 // Synchronously deletes |path|. |
| 69 filesystem::FileError Delete(OpaqueDir* dir, |
| 70 const std::string& path, |
| 71 uint32_t delete_flags); |
| 72 |
| 73 // Synchronously creates |path|. |
| 74 filesystem::FileError CreateDir(OpaqueDir* dir, const std::string& path); |
| 75 |
| 76 // Synchronously gets the size of a file. |
| 77 filesystem::FileError GetFileSize(OpaqueDir* dir, |
| 78 const std::string& path, |
| 79 uint64_t* file_size); |
| 80 |
| 81 // Synchronously renames a file. |
| 82 filesystem::FileError RenameFile(OpaqueDir* dir, |
| 83 const std::string& old_path, |
| 84 const std::string& new_path); |
| 85 |
| 86 // Synchronously locks a file. Returns both the file return code, and if OK, |
| 87 // an opaque object to the lock to enforce going through this interface to |
| 88 // unlock the file so that unlocking happens on the correct thread. |
| 89 std::pair<filesystem::FileError, OpaqueLock*> LockFile( |
| 90 OpaqueDir* dir, |
| 91 const std::string& path); |
| 92 |
| 93 // Unlocks a file. LevelDBMojoProxy takes ownership of lock. (We don't make |
| 94 // this a scoped_ptr because exporting the ctor/dtor for this struct publicly |
| 95 // defeats the purpose of the struct.) |
| 96 filesystem::FileError UnlockFile(OpaqueLock* lock); |
| 97 |
| 98 private: |
| 99 friend class base::RefCountedThreadSafe<LevelDBMojoProxy>; |
| 100 ~LevelDBMojoProxy(); |
| 101 |
| 102 void RunInternal(const base::Closure& task); |
| 103 |
| 104 void DoOnOtherThread(const base::Closure& c, base::WaitableEvent* event); |
| 105 |
| 106 // Implementation methods of the public interface. Depending on whether they |
| 107 // were called from the thread that |task_runner_| is, these might be run |
| 108 // on the current thread or through PostTask(). |
| 109 void RegisterDirectoryImpl( |
| 110 mojo::InterfacePtrInfo<filesystem::Directory> directory_info, |
| 111 OpaqueDir** out_dir); |
| 112 void UnregisterDirectoryImpl(OpaqueDir* dir); |
| 113 void OpenFileHandleImpl(OpaqueDir* dir, |
| 114 std::string name, |
| 115 uint32_t open_flags, |
| 116 base::File* out_file); |
| 117 void SyncDirectoryImpl(OpaqueDir* dir, |
| 118 std::string name, |
| 119 filesystem::FileError* out_error); |
| 120 void FileExistsImpl(OpaqueDir* dir, |
| 121 std::string name, |
| 122 bool* exists); |
| 123 void GetChildrenImpl(OpaqueDir* dir, |
| 124 std::string name, |
| 125 std::vector<std::string>* contents, |
| 126 filesystem::FileError* out_error); |
| 127 void DeleteImpl(OpaqueDir* dir, |
| 128 std::string name, |
| 129 uint32_t delete_flags, |
| 130 filesystem::FileError* out_error); |
| 131 void CreateDirImpl(OpaqueDir* dir, |
| 132 std::string name, |
| 133 filesystem::FileError* out_error); |
| 134 void GetFileSizeImpl(OpaqueDir* dir, |
| 135 const std::string& path, |
| 136 uint64_t* file_size, |
| 137 filesystem::FileError* out_error); |
| 138 void RenameFileImpl(OpaqueDir* dir, |
| 139 const std::string& old_path, |
| 140 const std::string& new_path, |
| 141 filesystem::FileError* out_error); |
| 142 void LockFileImpl(OpaqueDir* dir, |
| 143 const std::string& path, |
| 144 filesystem::FileError* out_error, |
| 145 OpaqueLock** out_lock); |
| 146 void UnlockFileImpl(scoped_ptr<OpaqueLock> lock, |
| 147 filesystem::FileError* out_error); |
| 148 |
| 149 // The task runner which represents the thread that all mojo objects are |
| 150 // bound to. |
| 151 scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
| 152 |
| 153 int outstanding_opaque_dirs_; |
| 154 |
| 155 DISALLOW_COPY_AND_ASSIGN(LevelDBMojoProxy); |
| 156 }; |
| 157 |
| 158 } // namespace leveldb |
| 159 |
| 160 #endif // COMPONENTS_LEVELDB_LEVELDB_MOJO_PROXY_H_ |
OLD | NEW |