OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2012 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 // This file defines FileStream::Context class. |
| 6 // The general design of FileStream is as follows: file_stream.h defines |
| 7 // FileStream class which basically is just an "wrapper" not containing any |
| 8 // specific implementation details. It re-routes all its method calls to |
| 9 // the instance of FileStream::Context (FileStream holds a scoped_ptr to |
| 10 // FileStream::Context instance). Context was extracted into a different class |
| 11 // to be able to do and finish all async operations even when FileStream |
| 12 // instance is deleted. So FileStream's destructor can schedule file |
| 13 // closing to be done by Context in WorkerPool and then just return (releasing |
| 14 // Context pointer from scoped_ptr) without waiting for actual closing to |
| 15 // complete. |
| 16 // Implementation of FileStream::Context is divided in two parts: some methods |
| 17 // and members are platform-independent and some depend on the platform. This |
| 18 // header file contains the complete definition of Context class including all |
| 19 // platform-dependent parts (because of that it has a lot of #if-#else |
| 20 // branching). Implementations of all platform-independent methods are |
| 21 // located in file_stream_context.cc, and all platform-dependent methods are |
| 22 // in file_stream_context_{win,posix}.cc. This separation provides better |
| 23 // readability of Context's code. And we tried to make as much Context code |
| 24 // platform-independent as possible. So file_stream_context_{win,posix}.cc are |
| 25 // much smaller than file_stream_context.cc now. |
| 26 |
| 27 #ifndef NET_BASE_FILE_STREAM_CONTEXT_H_ |
| 28 #define NET_BASE_FILE_STREAM_CONTEXT_H_ |
| 29 |
| 30 #include "base/message_loop.h" |
| 31 #include "base/platform_file.h" |
| 32 #include "net/base/completion_callback.h" |
| 33 #include "net/base/file_stream.h" |
| 34 #include "net/base/file_stream_metrics.h" |
| 35 #include "net/base/file_stream_whence.h" |
| 36 #include "net/base/net_log.h" |
| 37 |
| 38 #if defined(OS_POSIX) |
| 39 #include <errno.h> |
| 40 #endif |
| 41 |
| 42 class FilePath; |
| 43 |
| 44 namespace net { |
| 45 |
| 46 class IOBuffer; |
| 47 |
| 48 #if defined(OS_WIN) |
| 49 class FileStream::Context : public MessageLoopForIO::IOHandler { |
| 50 #elif defined(OS_POSIX) |
| 51 class FileStream::Context { |
| 52 #endif |
| 53 public: |
| 54 //////////////////////////////////////////////////////////////////////////// |
| 55 // Platform-dependent methods implemented in |
| 56 // file_stream_context_{win,posix}.cc. |
| 57 //////////////////////////////////////////////////////////////////////////// |
| 58 |
| 59 explicit Context(const BoundNetLog& bound_net_log); |
| 60 Context(base::PlatformFile file, |
| 61 const BoundNetLog& bound_net_log, |
| 62 int open_flags); |
| 63 #if defined(OS_WIN) |
| 64 virtual ~Context(); |
| 65 #elif defined(OS_POSIX) |
| 66 ~Context(); |
| 67 #endif |
| 68 |
| 69 int64 GetFileSize() const; |
| 70 |
| 71 int ReadAsync(IOBuffer* buf, |
| 72 int buf_len, |
| 73 const CompletionCallback& callback); |
| 74 int ReadSync(char* buf, int buf_len); |
| 75 |
| 76 int WriteAsync(IOBuffer* buf, |
| 77 int buf_len, |
| 78 const CompletionCallback& callback); |
| 79 int WriteSync(const char* buf, int buf_len); |
| 80 |
| 81 int Truncate(int64 bytes); |
| 82 |
| 83 //////////////////////////////////////////////////////////////////////////// |
| 84 // Inline methods. |
| 85 //////////////////////////////////////////////////////////////////////////// |
| 86 |
| 87 void set_record_uma(bool value) { record_uma_ = value; } |
| 88 base::PlatformFile file() const { return file_; } |
| 89 bool async_in_progress() const { return async_in_progress_; } |
| 90 |
| 91 //////////////////////////////////////////////////////////////////////////// |
| 92 // Platform-independent methods implemented in file_stream_context.cc. |
| 93 //////////////////////////////////////////////////////////////////////////// |
| 94 |
| 95 // Destroys the context. It can be deleted in the method or deletion can be |
| 96 // deferred if some asynchronous operation is now in progress or if file is |
| 97 // not closed yet. |
| 98 void Orphan(); |
| 99 |
| 100 void OpenAsync(const FilePath& path, |
| 101 int open_flags, |
| 102 const CompletionCallback& callback); |
| 103 int OpenSync(const FilePath& path, int open_flags); |
| 104 |
| 105 void CloseSync(); |
| 106 |
| 107 void SeekAsync(Whence whence, |
| 108 int64 offset, |
| 109 const Int64CompletionCallback& callback); |
| 110 int64 SeekSync(Whence whence, int64 offset); |
| 111 |
| 112 void FlushAsync(const CompletionCallback& callback); |
| 113 int FlushSync(); |
| 114 |
| 115 private: |
| 116 //////////////////////////////////////////////////////////////////////////// |
| 117 // Error code that is platform-dependent but is used in the platform- |
| 118 // independent code implemented in file_stream_context.cc. |
| 119 //////////////////////////////////////////////////////////////////////////// |
| 120 enum { |
| 121 #if defined(OS_WIN) |
| 122 ERROR_BAD_FILE = ERROR_INVALID_HANDLE |
| 123 #elif defined(OS_POSIX) |
| 124 ERROR_BAD_FILE = EBADF |
| 125 #endif |
| 126 }; |
| 127 |
| 128 //////////////////////////////////////////////////////////////////////////// |
| 129 // Platform-independent methods implemented in file_stream_context.cc. |
| 130 //////////////////////////////////////////////////////////////////////////// |
| 131 |
| 132 struct OpenResult { |
| 133 base::PlatformFile file; |
| 134 int error_code; |
| 135 }; |
| 136 |
| 137 // Map system error into network error code and log it with |bound_net_log_|. |
| 138 int RecordAndMapError(int error, FileErrorSource source) const; |
| 139 |
| 140 void BeginOpenEvent(const FilePath& path); |
| 141 |
| 142 OpenResult OpenFileImpl(const FilePath& path, int open_flags); |
| 143 |
| 144 int ProcessOpenError(int error_code); |
| 145 void OnOpenCompleted(const CompletionCallback& callback, OpenResult result); |
| 146 |
| 147 void CloseAndDelete(); |
| 148 void OnCloseCompleted(); |
| 149 |
| 150 Int64CompletionCallback IntToInt64(const CompletionCallback& callback); |
| 151 |
| 152 // Checks for IO error that probably happened in async methods. |
| 153 // If there was error reports it. |
| 154 void CheckForIOError(int64* result, FileErrorSource source); |
| 155 |
| 156 // Called when asynchronous Seek() is completed. |
| 157 // Reports error if needed and calls callback. |
| 158 void ProcessAsyncResult(const Int64CompletionCallback& callback, |
| 159 FileErrorSource source, |
| 160 int64 result); |
| 161 |
| 162 // Called when asynchronous Open() or Seek() |
| 163 // is completed. |result| contains the result or a network error code. |
| 164 void OnAsyncCompleted(const Int64CompletionCallback& callback, int64 result); |
| 165 |
| 166 //////////////////////////////////////////////////////////////////////////// |
| 167 // Helper stuff which is platform-dependent but is used in the platform- |
| 168 // independent code implemented in file_stream_context.cc. These helpers were |
| 169 // introduced solely to implement as much of the Context methods as |
| 170 // possible independently from platform. |
| 171 //////////////////////////////////////////////////////////////////////////// |
| 172 |
| 173 #if defined(OS_WIN) |
| 174 int GetLastErrno() { return GetLastError(); } |
| 175 void OnAsyncFileOpened(); |
| 176 #elif defined(OS_POSIX) |
| 177 int GetLastErrno() { return errno; } |
| 178 void OnAsyncFileOpened() {} |
| 179 void CancelIo(base::PlatformFile) {} |
| 180 #endif |
| 181 |
| 182 //////////////////////////////////////////////////////////////////////////// |
| 183 // Platform-dependent methods implemented in |
| 184 // file_stream_context_{win,posix}.cc. |
| 185 //////////////////////////////////////////////////////////////////////////// |
| 186 |
| 187 // Adjusts the position from where the data is read. |
| 188 int64 SeekFileImpl(Whence whence, int64 offset); |
| 189 |
| 190 // Flushes all data written to the stream. |
| 191 int64 FlushFileImpl(); |
| 192 |
| 193 #if defined(OS_WIN) |
| 194 void IOCompletionIsPending(const CompletionCallback& callback, IOBuffer* buf); |
| 195 |
| 196 // Implementation of MessageLoopForIO::IOHandler |
| 197 virtual void OnIOCompleted(MessageLoopForIO::IOContext* context, |
| 198 DWORD bytes_read, |
| 199 DWORD error) OVERRIDE; |
| 200 #elif defined(OS_POSIX) |
| 201 // ReadFileImpl() is a simple wrapper around read() that handles EINTR |
| 202 // signals and calls RecordAndMapError() to map errno to net error codes. |
| 203 int64 ReadFileImpl(scoped_refptr<IOBuffer> buf, int buf_len); |
| 204 |
| 205 // WriteFileImpl() is a simple wrapper around write() that handles EINTR |
| 206 // signals and calls MapSystemError() to map errno to net error codes. |
| 207 // It tries to write to completion. |
| 208 int64 WriteFileImpl(scoped_refptr<IOBuffer> buf, int buf_len); |
| 209 #endif |
| 210 |
| 211 base::PlatformFile file_; |
| 212 bool record_uma_; |
| 213 bool async_in_progress_; |
| 214 bool orphaned_; |
| 215 BoundNetLog bound_net_log_; |
| 216 |
| 217 #if defined(OS_WIN) |
| 218 MessageLoopForIO::IOContext io_context_; |
| 219 CompletionCallback callback_; |
| 220 scoped_refptr<IOBuffer> in_flight_buf_; |
| 221 FileErrorSource error_source_; |
| 222 #endif |
| 223 |
| 224 DISALLOW_COPY_AND_ASSIGN(Context); |
| 225 }; |
| 226 |
| 227 } // namespace net |
| 228 |
| 229 #endif // NET_BASE_FILE_STREAM_CONTEXT_H_ |
| 230 |
OLD | NEW |