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-reoutes all its method calls to | |
willchan no longer on Chromium
2012/11/02 19:06:05
re-routes
| |
9 // the instance of FileStream::Context (FileStream holds scoped_ptr to | |
willchan no longer on Chromium
2012/11/02 19:06:05
holds a scoped_ptr
| |
10 // FileStream::Context instance). Context was extracted into different class | |
willchan no longer on Chromium
2012/11/02 19:06:05
into a different
| |
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 complete definition of Context class including all | |
willchan no longer on Chromium
2012/11/02 19:06:05
contains the complete definition
| |
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 |