OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // For loading files, we make use of overlapped i/o to ensure that reading from | 5 // For loading files, we make use of overlapped i/o to ensure that reading from |
6 // the filesystem (e.g., a network filesystem) does not block the calling | 6 // the filesystem (e.g., a network filesystem) does not block the calling |
7 // thread. An alternative approach would be to use a background thread or pool | 7 // thread. An alternative approach would be to use a background thread or pool |
8 // of threads, but it seems better to leverage the operating system's ability | 8 // of threads, but it seems better to leverage the operating system's ability |
9 // to do background file reads for us. | 9 // to do background file reads for us. |
10 // | 10 // |
11 // Since overlapped reads require a 'static' buffer for the duration of the | 11 // Since overlapped reads require a 'static' buffer for the duration of the |
12 // asynchronous read, the URLRequestFileJob keeps a buffer as a member var. In | 12 // asynchronous read, the URLRequestFileJob keeps a buffer as a member var. In |
13 // URLRequestFileJob::Read, data is simply copied from the object's buffer into | 13 // URLRequestFileJob::Read, data is simply copied from the object's buffer into |
14 // the given buffer. If there is no data to copy, the URLRequestFileJob | 14 // the given buffer. If there is no data to copy, the URLRequestFileJob |
15 // attempts to read more from the file to fill its buffer. If reading from the | 15 // attempts to read more from the file to fill its buffer. If reading from the |
16 // file does not complete synchronously, then the URLRequestFileJob waits for a | 16 // file does not complete synchronously, then the URLRequestFileJob waits for a |
17 // signal from the OS that the overlapped read has completed. It does so by | 17 // signal from the OS that the overlapped read has completed. It does so by |
18 // leveraging the MessageLoop::WatchObject API. | 18 // leveraging the MessageLoop::WatchObject API. |
19 | 19 |
20 #include "net/url_request/url_request_file_job.h" | 20 #include "net/url_request/url_request_file_job.h" |
21 | 21 |
22 #include "base/bind.h" | 22 #include "base/bind.h" |
23 #include "base/compiler_specific.h" | 23 #include "base/compiler_specific.h" |
24 #include "base/file_util.h" | 24 #include "base/file_util.h" |
25 #include "base/message_loop/message_loop.h" | 25 #include "base/message_loop/message_loop.h" |
26 #include "base/platform_file.h" | 26 #include "base/platform_file.h" |
27 #include "base/strings/string_util.h" | 27 #include "base/strings/string_util.h" |
28 #include "base/synchronization/lock.h" | 28 #include "base/synchronization/lock.h" |
29 #include "base/task_runner.h" | |
29 #include "base/threading/thread_restrictions.h" | 30 #include "base/threading/thread_restrictions.h" |
30 #include "base/threading/worker_pool.h" | |
31 #include "build/build_config.h" | 31 #include "build/build_config.h" |
32 #include "net/base/file_stream.h" | 32 #include "net/base/file_stream.h" |
33 #include "net/base/io_buffer.h" | 33 #include "net/base/io_buffer.h" |
34 #include "net/base/load_flags.h" | 34 #include "net/base/load_flags.h" |
35 #include "net/base/mime_util.h" | 35 #include "net/base/mime_util.h" |
36 #include "net/base/net_errors.h" | 36 #include "net/base/net_errors.h" |
37 #include "net/base/net_util.h" | 37 #include "net/base/net_util.h" |
38 #include "net/http/http_util.h" | 38 #include "net/http/http_util.h" |
39 #include "net/url_request/url_request_error_job.h" | 39 #include "net/url_request/url_request_error_job.h" |
40 #include "net/url_request/url_request_file_dir_job.h" | 40 #include "net/url_request/url_request_file_dir_job.h" |
41 #include "url/gurl.h" | 41 #include "url/gurl.h" |
42 | 42 |
43 #if defined(OS_WIN) | 43 #if defined(OS_WIN) |
44 #include "base/win/shortcut.h" | 44 #include "base/win/shortcut.h" |
45 #endif | 45 #endif |
46 | 46 |
47 namespace net { | 47 namespace net { |
48 | 48 |
49 URLRequestFileJob::FileMetaInfo::FileMetaInfo() | 49 URLRequestFileJob::FileMetaInfo::FileMetaInfo() |
50 : file_size(0), | 50 : file_size(0), |
51 mime_type_result(false), | 51 mime_type_result(false), |
52 file_exists(false), | 52 file_exists(false), |
53 is_directory(false) { | 53 is_directory(false) { |
54 } | 54 } |
55 | 55 |
56 URLRequestFileJob::URLRequestFileJob(URLRequest* request, | 56 URLRequestFileJob::URLRequestFileJob( |
57 NetworkDelegate* network_delegate, | 57 URLRequest* request, NetworkDelegate* network_delegate, |
akalin
2013/08/16 21:22:20
one param per line
| |
58 const base::FilePath& file_path) | 58 const base::FilePath& file_path, |
59 const scoped_refptr<base::TaskRunner>& file_task_runner) | |
59 : URLRequestJob(request, network_delegate), | 60 : URLRequestJob(request, network_delegate), |
60 file_path_(file_path), | 61 file_path_(file_path), |
61 stream_(new FileStream(NULL)), | 62 stream_(new FileStream(NULL, file_task_runner)), |
63 file_task_runner_(file_task_runner), | |
62 remaining_bytes_(0), | 64 remaining_bytes_(0), |
63 weak_ptr_factory_(this) { | 65 weak_ptr_factory_(this) {} |
64 } | |
65 | 66 |
66 void URLRequestFileJob::Start() { | 67 void URLRequestFileJob::Start() { |
67 FileMetaInfo* meta_info = new FileMetaInfo(); | 68 FileMetaInfo* meta_info = new FileMetaInfo(); |
68 base::WorkerPool::PostTaskAndReply( | 69 file_task_runner_->PostTaskAndReply( |
69 FROM_HERE, | 70 FROM_HERE, |
70 base::Bind(&URLRequestFileJob::FetchMetaInfo, file_path_, | 71 base::Bind(&URLRequestFileJob::FetchMetaInfo, file_path_, |
71 base::Unretained(meta_info)), | 72 base::Unretained(meta_info)), |
72 base::Bind(&URLRequestFileJob::DidFetchMetaInfo, | 73 base::Bind(&URLRequestFileJob::DidFetchMetaInfo, |
73 weak_ptr_factory_.GetWeakPtr(), | 74 weak_ptr_factory_.GetWeakPtr(), |
74 base::Owned(meta_info)), | 75 base::Owned(meta_info))); |
75 true); | |
76 } | 76 } |
77 | 77 |
78 void URLRequestFileJob::Kill() { | 78 void URLRequestFileJob::Kill() { |
79 stream_.reset(); | 79 stream_.reset(); |
80 weak_ptr_factory_.InvalidateWeakPtrs(); | 80 weak_ptr_factory_.InvalidateWeakPtrs(); |
81 | 81 |
82 URLRequestJob::Kill(); | 82 URLRequestJob::Kill(); |
83 } | 83 } |
84 | 84 |
85 bool URLRequestFileJob::ReadRawData(IOBuffer* dest, int dest_size, | 85 bool URLRequestFileJob::ReadRawData(IOBuffer* dest, int dest_size, |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
291 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, result)); | 291 NotifyDone(URLRequestStatus(URLRequestStatus::FAILED, result)); |
292 } | 292 } |
293 | 293 |
294 remaining_bytes_ -= result; | 294 remaining_bytes_ -= result; |
295 DCHECK_GE(remaining_bytes_, 0); | 295 DCHECK_GE(remaining_bytes_, 0); |
296 | 296 |
297 NotifyReadComplete(result); | 297 NotifyReadComplete(result); |
298 } | 298 } |
299 | 299 |
300 } // namespace net | 300 } // namespace net |
OLD | NEW |