Index: net/base/file_stream_context.h |
diff --git a/net/base/file_stream_context.h b/net/base/file_stream_context.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..244c25f4c40d97d5a52a73b0f4805967673cf8ad |
--- /dev/null |
+++ b/net/base/file_stream_context.h |
@@ -0,0 +1,230 @@ |
+// Copyright (c) 2012 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. |
+ |
+// This file defines FileStream::Context class. |
+// The general design of FileStream is as follows: file_stream.h defines |
+// FileStream class which basically is just an "wrapper" not containing any |
+// specific implementation details. It re-routes all its method calls to |
+// the instance of FileStream::Context (FileStream holds a scoped_ptr to |
+// FileStream::Context instance). Context was extracted into a different class |
+// to be able to do and finish all async operations even when FileStream |
+// instance is deleted. So FileStream's destructor can schedule file |
+// closing to be done by Context in WorkerPool and then just return (releasing |
+// Context pointer from scoped_ptr) without waiting for actual closing to |
+// complete. |
+// Implementation of FileStream::Context is divided in two parts: some methods |
+// and members are platform-independent and some depend on the platform. This |
+// header file contains the complete definition of Context class including all |
+// platform-dependent parts (because of that it has a lot of #if-#else |
+// branching). Implementations of all platform-independent methods are |
+// located in file_stream_context.cc, and all platform-dependent methods are |
+// in file_stream_context_{win,posix}.cc. This separation provides better |
+// readability of Context's code. And we tried to make as much Context code |
+// platform-independent as possible. So file_stream_context_{win,posix}.cc are |
+// much smaller than file_stream_context.cc now. |
+ |
+#ifndef NET_BASE_FILE_STREAM_CONTEXT_H_ |
+#define NET_BASE_FILE_STREAM_CONTEXT_H_ |
+ |
+#include "base/message_loop.h" |
+#include "base/platform_file.h" |
+#include "net/base/completion_callback.h" |
+#include "net/base/file_stream.h" |
+#include "net/base/file_stream_metrics.h" |
+#include "net/base/file_stream_whence.h" |
+#include "net/base/net_log.h" |
+ |
+#if defined(OS_POSIX) |
+#include <errno.h> |
+#endif |
+ |
+class FilePath; |
+ |
+namespace net { |
+ |
+class IOBuffer; |
+ |
+#if defined(OS_WIN) |
+class FileStream::Context : public MessageLoopForIO::IOHandler { |
+#elif defined(OS_POSIX) |
+class FileStream::Context { |
+#endif |
+ public: |
+ //////////////////////////////////////////////////////////////////////////// |
+ // Platform-dependent methods implemented in |
+ // file_stream_context_{win,posix}.cc. |
+ //////////////////////////////////////////////////////////////////////////// |
+ |
+ explicit Context(const BoundNetLog& bound_net_log); |
+ Context(base::PlatformFile file, |
+ const BoundNetLog& bound_net_log, |
+ int open_flags); |
+#if defined(OS_WIN) |
+ virtual ~Context(); |
+#elif defined(OS_POSIX) |
+ ~Context(); |
+#endif |
+ |
+ int64 GetFileSize() const; |
+ |
+ int ReadAsync(IOBuffer* buf, |
+ int buf_len, |
+ const CompletionCallback& callback); |
+ int ReadSync(char* buf, int buf_len); |
+ |
+ int WriteAsync(IOBuffer* buf, |
+ int buf_len, |
+ const CompletionCallback& callback); |
+ int WriteSync(const char* buf, int buf_len); |
+ |
+ int Truncate(int64 bytes); |
+ |
+ //////////////////////////////////////////////////////////////////////////// |
+ // Inline methods. |
+ //////////////////////////////////////////////////////////////////////////// |
+ |
+ void set_record_uma(bool value) { record_uma_ = value; } |
+ base::PlatformFile file() const { return file_; } |
+ bool async_in_progress() const { return async_in_progress_; } |
+ |
+ //////////////////////////////////////////////////////////////////////////// |
+ // Platform-independent methods implemented in file_stream_context.cc. |
+ //////////////////////////////////////////////////////////////////////////// |
+ |
+ // Destroys the context. It can be deleted in the method or deletion can be |
+ // deferred if some asynchronous operation is now in progress or if file is |
+ // not closed yet. |
+ void Orphan(); |
+ |
+ void OpenAsync(const FilePath& path, |
+ int open_flags, |
+ const CompletionCallback& callback); |
+ int OpenSync(const FilePath& path, int open_flags); |
+ |
+ void CloseSync(); |
+ |
+ void SeekAsync(Whence whence, |
+ int64 offset, |
+ const Int64CompletionCallback& callback); |
+ int64 SeekSync(Whence whence, int64 offset); |
+ |
+ void FlushAsync(const CompletionCallback& callback); |
+ int FlushSync(); |
+ |
+ private: |
+ //////////////////////////////////////////////////////////////////////////// |
+ // Error code that is platform-dependent but is used in the platform- |
+ // independent code implemented in file_stream_context.cc. |
+ //////////////////////////////////////////////////////////////////////////// |
+ enum { |
+#if defined(OS_WIN) |
+ ERROR_BAD_FILE = ERROR_INVALID_HANDLE |
+#elif defined(OS_POSIX) |
+ ERROR_BAD_FILE = EBADF |
+#endif |
+ }; |
+ |
+ //////////////////////////////////////////////////////////////////////////// |
+ // Platform-independent methods implemented in file_stream_context.cc. |
+ //////////////////////////////////////////////////////////////////////////// |
+ |
+ struct OpenResult { |
+ base::PlatformFile file; |
+ int error_code; |
+ }; |
+ |
+ // Map system error into network error code and log it with |bound_net_log_|. |
+ int RecordAndMapError(int error, FileErrorSource source) const; |
+ |
+ void BeginOpenEvent(const FilePath& path); |
+ |
+ OpenResult OpenFileImpl(const FilePath& path, int open_flags); |
+ |
+ int ProcessOpenError(int error_code); |
+ void OnOpenCompleted(const CompletionCallback& callback, OpenResult result); |
+ |
+ void CloseAndDelete(); |
+ void OnCloseCompleted(); |
+ |
+ Int64CompletionCallback IntToInt64(const CompletionCallback& callback); |
+ |
+ // Checks for IO error that probably happened in async methods. |
+ // If there was error reports it. |
+ void CheckForIOError(int64* result, FileErrorSource source); |
+ |
+ // Called when asynchronous Seek() is completed. |
+ // Reports error if needed and calls callback. |
+ void ProcessAsyncResult(const Int64CompletionCallback& callback, |
+ FileErrorSource source, |
+ int64 result); |
+ |
+ // Called when asynchronous Open() or Seek() |
+ // is completed. |result| contains the result or a network error code. |
+ void OnAsyncCompleted(const Int64CompletionCallback& callback, int64 result); |
+ |
+ //////////////////////////////////////////////////////////////////////////// |
+ // Helper stuff which is platform-dependent but is used in the platform- |
+ // independent code implemented in file_stream_context.cc. These helpers were |
+ // introduced solely to implement as much of the Context methods as |
+ // possible independently from platform. |
+ //////////////////////////////////////////////////////////////////////////// |
+ |
+#if defined(OS_WIN) |
+ int GetLastErrno() { return GetLastError(); } |
+ void OnAsyncFileOpened(); |
+#elif defined(OS_POSIX) |
+ int GetLastErrno() { return errno; } |
+ void OnAsyncFileOpened() {} |
+ void CancelIo(base::PlatformFile) {} |
+#endif |
+ |
+ //////////////////////////////////////////////////////////////////////////// |
+ // Platform-dependent methods implemented in |
+ // file_stream_context_{win,posix}.cc. |
+ //////////////////////////////////////////////////////////////////////////// |
+ |
+ // Adjusts the position from where the data is read. |
+ int64 SeekFileImpl(Whence whence, int64 offset); |
+ |
+ // Flushes all data written to the stream. |
+ int64 FlushFileImpl(); |
+ |
+#if defined(OS_WIN) |
+ void IOCompletionIsPending(const CompletionCallback& callback, IOBuffer* buf); |
+ |
+ // Implementation of MessageLoopForIO::IOHandler |
+ virtual void OnIOCompleted(MessageLoopForIO::IOContext* context, |
+ DWORD bytes_read, |
+ DWORD error) OVERRIDE; |
+#elif defined(OS_POSIX) |
+ // ReadFileImpl() is a simple wrapper around read() that handles EINTR |
+ // signals and calls RecordAndMapError() to map errno to net error codes. |
+ int64 ReadFileImpl(scoped_refptr<IOBuffer> buf, int buf_len); |
+ |
+ // WriteFileImpl() is a simple wrapper around write() that handles EINTR |
+ // signals and calls MapSystemError() to map errno to net error codes. |
+ // It tries to write to completion. |
+ int64 WriteFileImpl(scoped_refptr<IOBuffer> buf, int buf_len); |
+#endif |
+ |
+ base::PlatformFile file_; |
+ bool record_uma_; |
+ bool async_in_progress_; |
+ bool orphaned_; |
+ BoundNetLog bound_net_log_; |
+ |
+#if defined(OS_WIN) |
+ MessageLoopForIO::IOContext io_context_; |
+ CompletionCallback callback_; |
+ scoped_refptr<IOBuffer> in_flight_buf_; |
+ FileErrorSource error_source_; |
+#endif |
+ |
+ DISALLOW_COPY_AND_ASSIGN(Context); |
+}; |
+ |
+} // namespace net |
+ |
+#endif // NET_BASE_FILE_STREAM_CONTEXT_H_ |
+ |