Add signalSyncPoint to the WebGraphicsContext3D command buffer impls.
[chromium-blink-merge.git] / net / base / file_stream_context_posix.cc
blob87fa1066ff37bb00dcaec0c8ea4e7eaabd4e491a
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.
5 // For 64-bit file access (off_t = off64_t, lseek64, etc).
6 #define _FILE_OFFSET_BITS 64
8 #include "net/base/file_stream_context.h"
10 #include <errno.h>
11 #include <fcntl.h>
12 #include <sys/stat.h>
13 #include <sys/types.h>
14 #include <unistd.h>
16 #include "base/basictypes.h"
17 #include "base/bind.h"
18 #include "base/bind_helpers.h"
19 #include "base/callback.h"
20 #include "base/files/file_path.h"
21 #include "base/location.h"
22 #include "base/logging.h"
23 #include "base/metrics/histogram.h"
24 #include "base/posix/eintr_wrapper.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"
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
38 namespace net {
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);
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);
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) {
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) {
66 FileStream::Context::~Context() {
69 int64 FileStream::Context::GetFileSize() const {
70 struct stat info;
71 if (fstat(file_, &info) != 0) {
72 IOResult result = IOResult::FromOSError(errno);
73 RecordError(result, FILE_ERROR_SOURCE_GET_SIZE);
74 return result.result;
77 return static_cast<int64>(info.st_size);
80 int FileStream::Context::ReadAsync(IOBuffer* in_buf,
81 int buf_len,
82 const CompletionCallback& callback) {
83 DCHECK(!async_in_progress_);
85 scoped_refptr<IOBuffer> buf = in_buf;
86 const bool posted = base::PostTaskAndReplyWithResult(
87 base::WorkerPool::GetTaskRunner(true /* task is slow */),
88 FROM_HERE,
89 base::Bind(&Context::ReadFileImpl,
90 base::Unretained(this), buf, buf_len),
91 base::Bind(&Context::ProcessAsyncResult,
92 base::Unretained(this), IntToInt64(callback),
93 FILE_ERROR_SOURCE_READ));
94 DCHECK(posted);
96 async_in_progress_ = true;
97 return ERR_IO_PENDING;
100 int FileStream::Context::ReadSync(char* in_buf, int buf_len) {
101 scoped_refptr<IOBuffer> buf = new WrappedIOBuffer(in_buf);
102 IOResult result = ReadFileImpl(buf, buf_len);
103 RecordError(result, FILE_ERROR_SOURCE_READ);
104 return result.result;
107 int FileStream::Context::WriteAsync(IOBuffer* in_buf,
108 int buf_len,
109 const CompletionCallback& callback) {
110 DCHECK(!async_in_progress_);
112 scoped_refptr<IOBuffer> buf = in_buf;
113 const bool posted = base::PostTaskAndReplyWithResult(
114 base::WorkerPool::GetTaskRunner(true /* task is slow */),
115 FROM_HERE,
116 base::Bind(&Context::WriteFileImpl,
117 base::Unretained(this), buf, buf_len),
118 base::Bind(&Context::ProcessAsyncResult,
119 base::Unretained(this), IntToInt64(callback),
120 FILE_ERROR_SOURCE_WRITE));
121 DCHECK(posted);
123 async_in_progress_ = true;
124 return ERR_IO_PENDING;
127 int FileStream::Context::WriteSync(const char* in_buf, int buf_len) {
128 scoped_refptr<IOBuffer> buf = new WrappedIOBuffer(in_buf);
129 IOResult result = WriteFileImpl(buf, buf_len);
130 RecordError(result, FILE_ERROR_SOURCE_WRITE);
131 return result.result;
134 int FileStream::Context::Truncate(int64 bytes) {
135 if (ftruncate(file_, bytes) != 0) {
136 IOResult result = IOResult::FromOSError(errno);
137 RecordError(result, FILE_ERROR_SOURCE_SET_EOF);
138 return result.result;
141 return bytes;
144 FileStream::Context::IOResult FileStream::Context::SeekFileImpl(Whence whence,
145 int64 offset) {
146 off_t res = lseek(file_, static_cast<off_t>(offset),
147 static_cast<int>(whence));
148 if (res == static_cast<off_t>(-1))
149 return IOResult::FromOSError(errno);
151 return IOResult(res, 0);
154 FileStream::Context::IOResult FileStream::Context::FlushFileImpl() {
155 ssize_t res = HANDLE_EINTR(fsync(file_));
156 if (res == -1)
157 return IOResult::FromOSError(errno);
159 return IOResult(res, 0);
162 FileStream::Context::IOResult FileStream::Context::ReadFileImpl(
163 scoped_refptr<IOBuffer> buf,
164 int buf_len) {
165 // Loop in the case of getting interrupted by a signal.
166 ssize_t res = HANDLE_EINTR(read(file_, buf->data(),
167 static_cast<size_t>(buf_len)));
168 if (res == -1)
169 return IOResult::FromOSError(errno);
171 return IOResult(res, 0);
174 FileStream::Context::IOResult FileStream::Context::WriteFileImpl(
175 scoped_refptr<IOBuffer> buf,
176 int buf_len) {
177 ssize_t res = HANDLE_EINTR(write(file_, buf->data(), buf_len));
178 if (res == -1)
179 return IOResult::FromOSError(errno);
181 return IOResult(res, 0);
184 } // namespace net