Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(34)

Side by Side Diff: net/base/file_stream_context_posix.cc

Issue 10701050: net: Implement canceling of all async operations in FileStream. (Closed) Base URL: https://src.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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 // For 64-bit file access (off_t = off64_t, lseek64, etc).
6 #define _FILE_OFFSET_BITS 64
7
8 #include "net/base/file_stream_context.h"
9
10 #include <sys/types.h>
11 #include <sys/stat.h>
12 #include <fcntl.h>
13 #include <unistd.h>
14 #include <errno.h>
15
16 #include "base/basictypes.h"
17 #include "base/bind.h"
18 #include "base/bind_helpers.h"
19 #include "base/callback.h"
20 #include "base/eintr_wrapper.h"
21 #include "base/file_path.h"
22 #include "base/location.h"
23 #include "base/logging.h"
24 #include "base/metrics/histogram.h"
25 #include "base/task_runner_util.h"
26 #include "base/threading/worker_pool.h"
27 #include "net/base/io_buffer.h"
28 #include "net/base/net_errors.h"
29
30 #if defined(OS_ANDROID)
31 // Android's bionic libc only supports the LFS transitional API.
32 #define off_t off64_t
33 #define lseek lseek64
34 #define stat stat64
35 #define fstat fstat64
36 #endif
37
38 namespace net {
39
40 // We cast back and forth, so make sure it's the size we're expecting.
41 COMPILE_ASSERT(sizeof(int64) == sizeof(off_t), off_t_64_bit);
42
43 // Make sure our Whence mappings match the system headers.
44 COMPILE_ASSERT(FROM_BEGIN == SEEK_SET &&
45 FROM_CURRENT == SEEK_CUR &&
46 FROM_END == SEEK_END, whence_matches_system);
47
48 FileStream::Context::Context(const BoundNetLog& bound_net_log)
49 : file_(base::kInvalidPlatformFileValue),
50 record_uma_(false),
51 async_in_progress_(false),
52 orphaned_(false),
53 bound_net_log_(bound_net_log) {
54 }
55
56 FileStream::Context::Context(base::PlatformFile file,
57 const BoundNetLog& bound_net_log,
58 int /* open_flags */)
59 : file_(file),
60 record_uma_(false),
61 async_in_progress_(false),
62 orphaned_(false),
63 bound_net_log_(bound_net_log) {
64 }
65
66 FileStream::Context::~Context() {
67 }
68
69 int64 FileStream::Context::GetFileSize() const {
70 struct stat info;
71 if (fstat(file_, &info) != 0)
72 return RecordAndMapError(errno, FILE_ERROR_SOURCE_GET_SIZE);
73
74 return static_cast<int64>(info.st_size);
75 }
76
77 int FileStream::Context::ReadAsync(IOBuffer* in_buf,
78 int buf_len,
79 const CompletionCallback& callback) {
80 DCHECK(!async_in_progress_);
81
82 scoped_refptr<IOBuffer> buf = in_buf;
83 const bool posted = base::PostTaskAndReplyWithResult(
84 base::WorkerPool::GetTaskRunner(true /* task is slow */),
85 FROM_HERE,
86 base::Bind(&Context::ReadFileImpl,
87 base::Unretained(this), buf, buf_len),
88 base::Bind(&Context::ProcessAsyncResult,
89 base::Unretained(this), IntToInt64(callback),
90 FILE_ERROR_SOURCE_READ));
91 DCHECK(posted);
92
93 async_in_progress_ = true;
94 return ERR_IO_PENDING;
95 }
96
97 int FileStream::Context::ReadSync(char* in_buf, int buf_len) {
98 scoped_refptr<IOBuffer> buf = new WrappedIOBuffer(in_buf);
99 int64 result = ReadFileImpl(buf, buf_len);
100 CheckForIOError(&result, FILE_ERROR_SOURCE_READ);
101 return result;
102 }
103
104 int FileStream::Context::WriteAsync(IOBuffer* in_buf,
105 int buf_len,
106 const CompletionCallback& callback) {
107 DCHECK(!async_in_progress_);
108
109 scoped_refptr<IOBuffer> buf = in_buf;
110 const bool posted = base::PostTaskAndReplyWithResult(
111 base::WorkerPool::GetTaskRunner(true /* task is slow */),
112 FROM_HERE,
113 base::Bind(&Context::WriteFileImpl,
114 base::Unretained(this), buf, buf_len),
115 base::Bind(&Context::ProcessAsyncResult,
116 base::Unretained(this), IntToInt64(callback),
117 FILE_ERROR_SOURCE_WRITE));
118 DCHECK(posted);
119
120 async_in_progress_ = true;
121 return ERR_IO_PENDING;
122 }
123
124 int FileStream::Context::WriteSync(const char* in_buf, int buf_len) {
125 scoped_refptr<IOBuffer> buf = new WrappedIOBuffer(in_buf);
126 int64 result = WriteFileImpl(buf, buf_len);
127 CheckForIOError(&result, FILE_ERROR_SOURCE_WRITE);
128 return result;
129 }
130
131 int FileStream::Context::Truncate(int64 bytes) {
132 int result = ftruncate(file_, bytes);
133 if (result == 0)
134 return bytes;
135
136 return RecordAndMapError(errno, FILE_ERROR_SOURCE_SET_EOF);
137 }
138
139 int64 FileStream::Context::SeekFileImpl(Whence whence, int64 offset) {
140 off_t res = lseek(file_, static_cast<off_t>(offset),
141 static_cast<int>(whence));
142 if (res == static_cast<off_t>(-1))
143 return errno;
144
145 return res;
146 }
147
148 int64 FileStream::Context::FlushFileImpl() {
149 ssize_t res = HANDLE_EINTR(fsync(file_));
150 if (res == -1)
151 return errno;
152
153 return res;
154 }
155
156 int64 FileStream::Context::ReadFileImpl(scoped_refptr<IOBuffer> buf,
157 int buf_len) {
158 // Loop in the case of getting interrupted by a signal.
159 ssize_t res = HANDLE_EINTR(read(file_, buf->data(),
160 static_cast<size_t>(buf_len)));
161 if (res == -1)
162 return errno;
163
164 return res;
165 }
166
167 int64 FileStream::Context::WriteFileImpl(scoped_refptr<IOBuffer> buf,
168 int buf_len) {
169 ssize_t res = HANDLE_EINTR(write(file_, buf->data(), buf_len));
170 if (res == -1)
171 return errno;
172
173 return res;
174 }
175
176 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698