Avi Drissman | 6459548 | 2022-09-14 20:52:29 | [diff] [blame] | 1 | // Copyright 2012 The Chromium Authors |
license.bot | bf09a50 | 2008-08-24 00:55:55 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 4 | |
[email protected] | c2c5cfc | 2014-03-03 16:35:28 | [diff] [blame] | 5 | #include "net/disk_cache/blockfile/file.h" |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 6 | |
Peter Kasting | 47b48940 | 2025-01-01 02:08:02 | [diff] [blame] | 7 | #include <windows.h> |
| 8 | |
avi | 51ba3e69 | 2015-12-26 17:30:50 | [diff] [blame] | 9 | #include <limits.h> |
Tom Sepez | e9b4dd55 | 2024-08-14 22:44:29 | [diff] [blame] | 10 | |
dcheng | 70c4942 | 2016-03-02 23:20:34 | [diff] [blame] | 11 | #include <utility> |
avi | 51ba3e69 | 2015-12-26 17:30:50 | [diff] [blame] | 12 | |
Tom Sepez | e9b4dd55 | 2024-08-14 22:44:29 | [diff] [blame] | 13 | #include "base/compiler_specific.h" |
[email protected] | 5799981 | 2013-02-24 05:40:52 | [diff] [blame] | 14 | #include "base/files/file_path.h" |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 15 | #include "base/memory/raw_ptr.h" |
Gabriel Charette | 19d2ae6 | 2018-04-10 14:10:58 | [diff] [blame] | 16 | #include "base/message_loop/message_pump_for_io.h" |
Adam Rice | f48f6e3 | 2023-03-30 02:03:57 | [diff] [blame] | 17 | #include "base/no_destructor.h" |
Sigurdur Asgeirsson | 8dbbea8 | 2021-03-04 16:50:32 | [diff] [blame] | 18 | #include "base/run_loop.h" |
jdoerrie | 6312bf6 | 2019-02-01 22:03:42 | [diff] [blame] | 19 | #include "base/strings/string_util.h" |
Carlos Caballero | b25fe847 | 2020-07-17 10:27:17 | [diff] [blame] | 20 | #include "base/task/current_thread.h" |
Sigurdur Asgeirsson | 8dbbea8 | 2021-03-04 16:50:32 | [diff] [blame] | 21 | #include "base/task/thread_pool.h" |
| 22 | #include "base/task/thread_pool/thread_pool_instance.h" |
| 23 | #include "base/threading/platform_thread.h" |
[email protected] | e25d44d | 2011-07-13 18:41:58 | [diff] [blame] | 24 | #include "net/base/net_errors.h" |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 25 | #include "net/disk_cache/disk_cache.h" |
| 26 | |
| 27 | namespace { |
| 28 | |
Konstantin Ganenko | aba55d2 | 2017-12-12 21:30:55 | [diff] [blame] | 29 | class CompletionHandler; |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 30 | // Structure used for asynchronous operations. |
| 31 | struct MyOverlapped { |
[email protected] | 17b8914 | 2008-11-07 21:52:15 | [diff] [blame] | 32 | MyOverlapped(disk_cache::File* file, size_t offset, |
| 33 | disk_cache::FileIOCallback* callback); |
Peter Kasting | 47b48940 | 2025-01-01 02:08:02 | [diff] [blame] | 34 | ~MyOverlapped() = default; |
| 35 | OVERLAPPED* overlapped() { return context_.GetOverlapped(); } |
[email protected] | 17b8914 | 2008-11-07 21:52:15 | [diff] [blame] | 36 | |
Gabriel Charette | 19d2ae6 | 2018-04-10 14:10:58 | [diff] [blame] | 37 | base::MessagePumpForIO::IOContext context_; |
[email protected] | 17b8914 | 2008-11-07 21:52:15 | [diff] [blame] | 38 | scoped_refptr<disk_cache::File> file_; |
Konstantin Ganenko | aba55d2 | 2017-12-12 21:30:55 | [diff] [blame] | 39 | scoped_refptr<CompletionHandler> completion_handler_; |
Keishi Hattori | 0e45c02 | 2021-11-27 09:25:52 | [diff] [blame] | 40 | raw_ptr<disk_cache::FileIOCallback> callback_; |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 41 | }; |
| 42 | |
mostynb | 91e0da98 | 2015-01-20 19:17:27 | [diff] [blame] | 43 | static_assert(offsetof(MyOverlapped, context_) == 0, |
| 44 | "should start with overlapped"); |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 45 | |
[email protected] | 17b8914 | 2008-11-07 21:52:15 | [diff] [blame] | 46 | // Helper class to handle the IO completion notifications from the message loop. |
Adam Rice | f48f6e3 | 2023-03-30 02:03:57 | [diff] [blame] | 47 | class CompletionHandler final : public base::MessagePumpForIO::IOHandler, |
| 48 | public base::RefCounted<CompletionHandler> { |
Konstantin Ganenko | aba55d2 | 2017-12-12 21:30:55 | [diff] [blame] | 49 | public: |
Gabriel Charette | 96d5c64 | 2020-04-09 20:31:10 | [diff] [blame] | 50 | CompletionHandler() : base::MessagePumpForIO::IOHandler(FROM_HERE) {} |
Konstantin Ganenko | aba55d2 | 2017-12-12 21:30:55 | [diff] [blame] | 51 | static CompletionHandler* Get(); |
| 52 | |
Peter Boström | 407869b | 2021-10-07 04:42:48 | [diff] [blame] | 53 | CompletionHandler(const CompletionHandler&) = delete; |
| 54 | CompletionHandler& operator=(const CompletionHandler&) = delete; |
| 55 | |
Konstantin Ganenko | aba55d2 | 2017-12-12 21:30:55 | [diff] [blame] | 56 | private: |
| 57 | friend class base::RefCounted<CompletionHandler>; |
| 58 | ~CompletionHandler() override {} |
| 59 | |
Gabriel Charette | 19d2ae6 | 2018-04-10 14:10:58 | [diff] [blame] | 60 | // implement base::MessagePumpForIO::IOHandler. |
| 61 | void OnIOCompleted(base::MessagePumpForIO::IOContext* context, |
dcheng | af6908f6 | 2015-04-17 23:31:05 | [diff] [blame] | 62 | DWORD actual_bytes, |
| 63 | DWORD error) override; |
[email protected] | 17b8914 | 2008-11-07 21:52:15 | [diff] [blame] | 64 | }; |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 65 | |
Konstantin Ganenko | aba55d2 | 2017-12-12 21:30:55 | [diff] [blame] | 66 | CompletionHandler* CompletionHandler::Get() { |
Adam Rice | f48f6e3 | 2023-03-30 02:03:57 | [diff] [blame] | 67 | static base::NoDestructor<scoped_refptr<CompletionHandler>> handler( |
| 68 | base::MakeRefCounted<CompletionHandler>()); |
| 69 | return handler->get(); |
Konstantin Ganenko | aba55d2 | 2017-12-12 21:30:55 | [diff] [blame] | 70 | } |
[email protected] | 625332e0 | 2010-12-14 07:48:49 | [diff] [blame] | 71 | |
[email protected] | 2da659e | 2013-05-23 20:51:34 | [diff] [blame] | 72 | void CompletionHandler::OnIOCompleted( |
Gabriel Charette | 19d2ae6 | 2018-04-10 14:10:58 | [diff] [blame] | 73 | base::MessagePumpForIO::IOContext* context, |
[email protected] | 2da659e | 2013-05-23 20:51:34 | [diff] [blame] | 74 | DWORD actual_bytes, |
| 75 | DWORD error) { |
[email protected] | 17b8914 | 2008-11-07 21:52:15 | [diff] [blame] | 76 | MyOverlapped* data = reinterpret_cast<MyOverlapped*>(context); |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 77 | |
| 78 | if (error) { |
| 79 | DCHECK(!actual_bytes); |
[email protected] | e25d44d | 2011-07-13 18:41:58 | [diff] [blame] | 80 | actual_bytes = static_cast<DWORD>(net::ERR_CACHE_READ_FAILURE); |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 81 | } |
| 82 | |
Paul Semel | a164794 | 2022-09-15 16:11:02 | [diff] [blame] | 83 | // `callback_` may self delete while in `OnFileIOComplete`. |
[email protected] | 17b8914 | 2008-11-07 21:52:15 | [diff] [blame] | 84 | if (data->callback_) |
Paul Semel | a164794 | 2022-09-15 16:11:02 | [diff] [blame] | 85 | data->callback_.ExtractAsDangling()->OnFileIOComplete( |
| 86 | static_cast<int>(actual_bytes)); |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 87 | |
[email protected] | 17b8914 | 2008-11-07 21:52:15 | [diff] [blame] | 88 | delete data; |
| 89 | } |
| 90 | |
| 91 | MyOverlapped::MyOverlapped(disk_cache::File* file, size_t offset, |
| 92 | disk_cache::FileIOCallback* callback) { |
Peter Kasting | 47b48940 | 2025-01-01 02:08:02 | [diff] [blame] | 93 | context_.GetOverlapped()->Offset = static_cast<DWORD>(offset); |
[email protected] | 17b8914 | 2008-11-07 21:52:15 | [diff] [blame] | 94 | file_ = file; |
| 95 | callback_ = callback; |
Konstantin Ganenko | aba55d2 | 2017-12-12 21:30:55 | [diff] [blame] | 96 | completion_handler_ = CompletionHandler::Get(); |
[email protected] | 17b8914 | 2008-11-07 21:52:15 | [diff] [blame] | 97 | } |
| 98 | |
[email protected] | 17b8914 | 2008-11-07 21:52:15 | [diff] [blame] | 99 | } // namespace |
| 100 | |
| 101 | namespace disk_cache { |
| 102 | |
[email protected] | 04ba182 | 2014-04-03 22:44:09 | [diff] [blame] | 103 | File::File(base::File file) |
dcheng | 70c4942 | 2016-03-02 23:20:34 | [diff] [blame] | 104 | : init_(true), mixed_(true), sync_base_file_(std::move(file)) {} |
[email protected] | 408d35f5 | 2008-08-13 18:30:22 | [diff] [blame] | 105 | |
[email protected] | 6cdfd7f | 2013-02-08 20:40:15 | [diff] [blame] | 106 | bool File::Init(const base::FilePath& name) { |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 107 | DCHECK(!init_); |
| 108 | if (init_) |
| 109 | return false; |
| 110 | |
[email protected] | 10f2e69 | 2010-09-29 21:00:35 | [diff] [blame] | 111 | DWORD sharing = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; |
| 112 | DWORD access = GENERIC_READ | GENERIC_WRITE | DELETE; |
Jan Wilken Dörrie | 9720dce | 2020-07-21 17:14:23 | [diff] [blame] | 113 | base_file_ = |
| 114 | base::File(CreateFile(name.value().c_str(), access, sharing, nullptr, |
| 115 | OPEN_EXISTING, FILE_FLAG_OVERLAPPED, nullptr)); |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 116 | |
[email protected] | 04ba182 | 2014-04-03 22:44:09 | [diff] [blame] | 117 | if (!base_file_.IsValid()) |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 118 | return false; |
| 119 | |
François Doray | 5b78590 | 2024-11-05 14:32:04 | [diff] [blame] | 120 | if (!base::CurrentIOThread::Get()->RegisterIOHandler( |
| 121 | base_file_.GetPlatformFile(), CompletionHandler::Get())) { |
| 122 | return false; |
| 123 | } |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 124 | |
[email protected] | 17b8914 | 2008-11-07 21:52:15 | [diff] [blame] | 125 | init_ = true; |
Jan Wilken Dörrie | 9720dce | 2020-07-21 17:14:23 | [diff] [blame] | 126 | sync_base_file_ = base::File(CreateFile(name.value().c_str(), access, sharing, |
| 127 | nullptr, OPEN_EXISTING, 0, nullptr)); |
[email protected] | 17b8914 | 2008-11-07 21:52:15 | [diff] [blame] | 128 | |
[email protected] | 04ba182 | 2014-04-03 22:44:09 | [diff] [blame] | 129 | if (!sync_base_file_.IsValid()) |
[email protected] | 17b8914 | 2008-11-07 21:52:15 | [diff] [blame] | 130 | return false; |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 131 | |
| 132 | return true; |
| 133 | } |
| 134 | |
[email protected] | 408d35f5 | 2008-08-13 18:30:22 | [diff] [blame] | 135 | bool File::IsValid() const { |
| 136 | if (!init_) |
| 137 | return false; |
[email protected] | 04ba182 | 2014-04-03 22:44:09 | [diff] [blame] | 138 | return base_file_.IsValid() || sync_base_file_.IsValid(); |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 139 | } |
| 140 | |
weidongliu | abbe232 | 2025-05-28 02:24:27 | [diff] [blame] | 141 | bool File::Read(base::span<uint8_t> buffer, size_t offset) { |
[email protected] | 408d35f5 | 2008-08-13 18:30:22 | [diff] [blame] | 142 | DCHECK(init_); |
weidongliu | abbe232 | 2025-05-28 02:24:27 | [diff] [blame] | 143 | if (buffer.size() > ULONG_MAX || offset > LONG_MAX) { |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 144 | return false; |
weidongliu | abbe232 | 2025-05-28 02:24:27 | [diff] [blame] | 145 | } |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 146 | |
weidongliu | abbe232 | 2025-05-28 02:24:27 | [diff] [blame] | 147 | std::optional<size_t> ret = sync_base_file_.Read(offset, buffer); |
| 148 | return ret == buffer.size(); |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 149 | } |
| 150 | |
weidongliu | abbe232 | 2025-05-28 02:24:27 | [diff] [blame] | 151 | bool File::Write(base::span<const uint8_t> buffer, size_t offset) { |
[email protected] | 408d35f5 | 2008-08-13 18:30:22 | [diff] [blame] | 152 | DCHECK(init_); |
weidongliu | abbe232 | 2025-05-28 02:24:27 | [diff] [blame] | 153 | if (buffer.size() > ULONG_MAX || offset > ULONG_MAX) { |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 154 | return false; |
weidongliu | abbe232 | 2025-05-28 02:24:27 | [diff] [blame] | 155 | } |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 156 | |
weidongliu | abbe232 | 2025-05-28 02:24:27 | [diff] [blame] | 157 | std::optional<size_t> ret = sync_base_file_.Write(offset, buffer); |
| 158 | return ret == buffer.size(); |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 159 | } |
| 160 | |
| 161 | // We have to increase the ref counter of the file before performing the IO to |
| 162 | // prevent the completion to happen with an invalid handle (if the file is |
| 163 | // closed while the IO is in flight). |
weidongliu | abbe232 | 2025-05-28 02:24:27 | [diff] [blame] | 164 | bool File::Read(base::span<uint8_t> buffer, |
| 165 | size_t offset, |
| 166 | FileIOCallback* callback, |
| 167 | bool* completed) { |
[email protected] | 408d35f5 | 2008-08-13 18:30:22 | [diff] [blame] | 168 | DCHECK(init_); |
[email protected] | f3c56e7 | 2009-08-21 18:35:24 | [diff] [blame] | 169 | if (!callback) { |
| 170 | if (completed) |
| 171 | *completed = true; |
weidongliu | abbe232 | 2025-05-28 02:24:27 | [diff] [blame] | 172 | return Read(buffer, offset); |
[email protected] | f3c56e7 | 2009-08-21 18:35:24 | [diff] [blame] | 173 | } |
[email protected] | 17b8914 | 2008-11-07 21:52:15 | [diff] [blame] | 174 | |
weidongliu | abbe232 | 2025-05-28 02:24:27 | [diff] [blame] | 175 | if (buffer.size() > ULONG_MAX || offset > ULONG_MAX) { |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 176 | return false; |
weidongliu | abbe232 | 2025-05-28 02:24:27 | [diff] [blame] | 177 | } |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 178 | |
[email protected] | 17b8914 | 2008-11-07 21:52:15 | [diff] [blame] | 179 | MyOverlapped* data = new MyOverlapped(this, offset, callback); |
weidongliu | abbe232 | 2025-05-28 02:24:27 | [diff] [blame] | 180 | DWORD size = static_cast<DWORD>(buffer.size()); |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 181 | |
[email protected] | 17b8914 | 2008-11-07 21:52:15 | [diff] [blame] | 182 | DWORD actual; |
weidongliu | abbe232 | 2025-05-28 02:24:27 | [diff] [blame] | 183 | if (!ReadFile(base_file_.GetPlatformFile(), buffer.data(), size, &actual, |
[email protected] | 04ba182 | 2014-04-03 22:44:09 | [diff] [blame] | 184 | data->overlapped())) { |
[email protected] | 17b8914 | 2008-11-07 21:52:15 | [diff] [blame] | 185 | *completed = false; |
| 186 | if (GetLastError() == ERROR_IO_PENDING) |
| 187 | return true; |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 188 | delete data; |
| 189 | return false; |
| 190 | } |
| 191 | |
[email protected] | 17b8914 | 2008-11-07 21:52:15 | [diff] [blame] | 192 | // The operation completed already. We'll be called back anyway. |
| 193 | *completed = (actual == size); |
[email protected] | c34e9a7a | 2011-05-11 12:06:57 | [diff] [blame] | 194 | DCHECK_EQ(size, actual); |
Raul Tambre | 94493c65 | 2019-03-11 17:18:35 | [diff] [blame] | 195 | data->callback_ = nullptr; |
| 196 | data->file_ = nullptr; // There is no reason to hold on to this anymore. |
[email protected] | 17b8914 | 2008-11-07 21:52:15 | [diff] [blame] | 197 | return *completed; |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 198 | } |
| 199 | |
weidongliu | abbe232 | 2025-05-28 02:24:27 | [diff] [blame] | 200 | bool File::Write(base::span<const uint8_t> buffer, |
| 201 | size_t offset, |
| 202 | FileIOCallback* callback, |
| 203 | bool* completed) { |
[email protected] | 408d35f5 | 2008-08-13 18:30:22 | [diff] [blame] | 204 | DCHECK(init_); |
[email protected] | f3c56e7 | 2009-08-21 18:35:24 | [diff] [blame] | 205 | if (!callback) { |
| 206 | if (completed) |
| 207 | *completed = true; |
weidongliu | abbe232 | 2025-05-28 02:24:27 | [diff] [blame] | 208 | return Write(buffer, offset); |
[email protected] | f3c56e7 | 2009-08-21 18:35:24 | [diff] [blame] | 209 | } |
[email protected] | 17b8914 | 2008-11-07 21:52:15 | [diff] [blame] | 210 | |
weidongliu | abbe232 | 2025-05-28 02:24:27 | [diff] [blame] | 211 | return AsyncWrite(buffer, offset, callback, completed); |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 212 | } |
| 213 | |
Tsuyoshi Horo | 07c3f0e | 2022-06-16 07:30:47 | [diff] [blame] | 214 | File::~File() = default; |
[email protected] | 04ba182 | 2014-04-03 22:44:09 | [diff] [blame] | 215 | |
| 216 | base::PlatformFile File::platform_file() const { |
| 217 | DCHECK(init_); |
| 218 | return base_file_.IsValid() ? base_file_.GetPlatformFile() : |
| 219 | sync_base_file_.GetPlatformFile(); |
| 220 | } |
| 221 | |
weidongliu | abbe232 | 2025-05-28 02:24:27 | [diff] [blame] | 222 | bool File::AsyncWrite(base::span<const uint8_t> buffer, |
| 223 | size_t offset, |
| 224 | FileIOCallback* callback, |
| 225 | bool* completed) { |
[email protected] | 408d35f5 | 2008-08-13 18:30:22 | [diff] [blame] | 226 | DCHECK(init_); |
[email protected] | e1fcf14 | 2010-08-23 18:47:25 | [diff] [blame] | 227 | DCHECK(callback); |
| 228 | DCHECK(completed); |
weidongliu | abbe232 | 2025-05-28 02:24:27 | [diff] [blame] | 229 | if (buffer.size() > ULONG_MAX || offset > ULONG_MAX) { |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 230 | return false; |
weidongliu | abbe232 | 2025-05-28 02:24:27 | [diff] [blame] | 231 | } |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 232 | |
[email protected] | 17b8914 | 2008-11-07 21:52:15 | [diff] [blame] | 233 | MyOverlapped* data = new MyOverlapped(this, offset, callback); |
weidongliu | abbe232 | 2025-05-28 02:24:27 | [diff] [blame] | 234 | DWORD size = static_cast<DWORD>(buffer.size()); |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 235 | |
[email protected] | 17b8914 | 2008-11-07 21:52:15 | [diff] [blame] | 236 | DWORD actual; |
weidongliu | abbe232 | 2025-05-28 02:24:27 | [diff] [blame] | 237 | if (!WriteFile(base_file_.GetPlatformFile(), buffer.data(), size, &actual, |
[email protected] | 04ba182 | 2014-04-03 22:44:09 | [diff] [blame] | 238 | data->overlapped())) { |
[email protected] | 17b8914 | 2008-11-07 21:52:15 | [diff] [blame] | 239 | *completed = false; |
| 240 | if (GetLastError() == ERROR_IO_PENDING) |
| 241 | return true; |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 242 | delete data; |
| 243 | return false; |
| 244 | } |
| 245 | |
[email protected] | 17b8914 | 2008-11-07 21:52:15 | [diff] [blame] | 246 | // The operation completed already. We'll be called back anyway. |
| 247 | *completed = (actual == size); |
[email protected] | c34e9a7a | 2011-05-11 12:06:57 | [diff] [blame] | 248 | DCHECK_EQ(size, actual); |
Raul Tambre | 94493c65 | 2019-03-11 17:18:35 | [diff] [blame] | 249 | data->callback_ = nullptr; |
| 250 | data->file_ = nullptr; // There is no reason to hold on to this anymore. |
[email protected] | 17b8914 | 2008-11-07 21:52:15 | [diff] [blame] | 251 | return *completed; |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 252 | } |
| 253 | |
| 254 | bool File::SetLength(size_t length) { |
[email protected] | 408d35f5 | 2008-08-13 18:30:22 | [diff] [blame] | 255 | DCHECK(init_); |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 256 | if (length > ULONG_MAX) |
| 257 | return false; |
| 258 | |
| 259 | DWORD size = static_cast<DWORD>(length); |
[email protected] | 21da6eb | 2008-11-03 17:18:14 | [diff] [blame] | 260 | HANDLE file = platform_file(); |
Raul Tambre | 94493c65 | 2019-03-11 17:18:35 | [diff] [blame] | 261 | if (INVALID_SET_FILE_POINTER == |
| 262 | SetFilePointer(file, size, nullptr, FILE_BEGIN)) |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 263 | return false; |
| 264 | |
[email protected] | 408d35f5 | 2008-08-13 18:30:22 | [diff] [blame] | 265 | return TRUE == SetEndOfFile(file); |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 266 | } |
| 267 | |
| 268 | size_t File::GetLength() { |
[email protected] | 408d35f5 | 2008-08-13 18:30:22 | [diff] [blame] | 269 | DCHECK(init_); |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 270 | LARGE_INTEGER size; |
[email protected] | 21da6eb | 2008-11-03 17:18:14 | [diff] [blame] | 271 | HANDLE file = platform_file(); |
[email protected] | 408d35f5 | 2008-08-13 18:30:22 | [diff] [blame] | 272 | if (!GetFileSizeEx(file, &size)) |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 273 | return 0; |
| 274 | if (size.HighPart) |
| 275 | return ULONG_MAX; |
| 276 | |
| 277 | return static_cast<size_t>(size.LowPart); |
| 278 | } |
| 279 | |
[email protected] | f3c56e7 | 2009-08-21 18:35:24 | [diff] [blame] | 280 | // Static. |
Sigurdur Asgeirsson | 8dbbea8 | 2021-03-04 16:50:32 | [diff] [blame] | 281 | void File::WaitForPendingIOForTesting(int* num_pending_io) { |
| 282 | // Spin on the burn-down count until the file IO completes. |
Peter Kasting | e5a38ed | 2021-10-02 03:06:35 | [diff] [blame] | 283 | constexpr base::TimeDelta kMillisecond = base::Milliseconds(1); |
Sigurdur Asgeirsson | 8dbbea8 | 2021-03-04 16:50:32 | [diff] [blame] | 284 | for (; *num_pending_io; base::PlatformThread::Sleep(kMillisecond)) { |
| 285 | // This waits for callbacks running on worker threads. |
| 286 | base::ThreadPoolInstance::Get()->FlushForTesting(); // IN-TEST |
| 287 | // This waits for the "Reply" tasks running on the current MessageLoop. |
| 288 | base::RunLoop().RunUntilIdle(); |
Takumi Fujimoto | 4fbd4f1 | 2021-03-03 17:38:13 | [diff] [blame] | 289 | } |
[email protected] | f3c56e7 | 2009-08-21 18:35:24 | [diff] [blame] | 290 | } |
| 291 | |
[email protected] | 48a109f | 2014-01-08 06:16:22 | [diff] [blame] | 292 | // Static. |
| 293 | void File::DropPendingIO() { |
| 294 | } |
| 295 | |
initial.commit | 586acc5fe | 2008-07-26 22:42:52 | [diff] [blame] | 296 | } // namespace disk_cache |