summaryrefslogtreecommitdiffstats
path: root/net/disk_cache
diff options
context:
space:
mode:
authorrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-13 18:30:22 +0000
committerrvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-13 18:30:22 +0000
commit408d35f5f5c316b2f8df12be606a8ff8921ba5ca (patch)
tree44323772354a63ac53bb48997523abf37707ef1e /net/disk_cache
parent9fa3c108d312d6664c51f02f203bc60fd4750156 (diff)
downloadchromium_src-408d35f5f5c316b2f8df12be606a8ff8921ba5ca.zip
chromium_src-408d35f5f5c316b2f8df12be606a8ff8921ba5ca.tar.gz
chromium_src-408d35f5f5c316b2f8df12be606a8ff8921ba5ca.tar.bz2
Move remaining OS dependent bits from the main logic on the disk cache.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@819 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/disk_cache')
-rw-r--r--net/disk_cache/backend_impl.cc112
-rw-r--r--net/disk_cache/backend_impl.h2
-rw-r--r--net/disk_cache/block_files.cc15
-rw-r--r--net/disk_cache/cache_util.h59
-rw-r--r--net/disk_cache/cache_util_posix.cc62
-rw-r--r--net/disk_cache/cache_util_win.cc116
-rw-r--r--net/disk_cache/file.cc71
-rw-r--r--net/disk_cache/file.h32
-rw-r--r--net/disk_cache/file_block.h2
-rw-r--r--net/disk_cache/mapped_file.cc2
-rw-r--r--net/disk_cache/mapped_file.h2
-rw-r--r--net/disk_cache/mem_backend_impl.cc14
-rw-r--r--net/disk_cache/mem_backend_impl.h4
-rw-r--r--net/disk_cache/os_file.h64
-rw-r--r--net/disk_cache/os_file_posix.cc41
-rw-r--r--net/disk_cache/os_file_win.cc81
-rw-r--r--net/disk_cache/rankings.h2
-rw-r--r--net/disk_cache/storage_block-inl.h2
-rw-r--r--net/disk_cache/storage_block.h2
19 files changed, 535 insertions, 150 deletions
diff --git a/net/disk_cache/backend_impl.cc b/net/disk_cache/backend_impl.cc
index 9ffb97e..38d17d6 100644
--- a/net/disk_cache/backend_impl.cc
+++ b/net/disk_cache/backend_impl.cc
@@ -32,13 +32,14 @@
#include "base/file_util.h"
#include "base/histogram.h"
#include "base/message_loop.h"
-#include "base/scoped_handle.h"
#include "base/string_util.h"
#include "base/timer.h"
#include "base/worker_pool.h"
+#include "net/disk_cache/cache_util.h"
#include "net/disk_cache/entry_impl.h"
#include "net/disk_cache/errors.h"
#include "net/disk_cache/hash.h"
+#include "net/disk_cache/file.h"
namespace {
@@ -74,44 +75,6 @@ size_t GetIndexSize(int table_len) {
return sizeof(disk_cache::IndexHeader) + table_size;
}
-// Deletes all the files on path that match search_name pattern.
-// Do not call this function with "*" as search_name.
-bool DeleteFiles(const wchar_t* path, const wchar_t* search_name) {
- std::wstring name(path);
- name += search_name;
- DCHECK(search_name[0] == L'\\');
-
- WIN32_FIND_DATA data;
- ScopedFindFileHandle handle(FindFirstFile(name.c_str(), &data));
- if (!handle.IsValid()) {
- DWORD error = GetLastError();
- return ERROR_FILE_NOT_FOUND == error;
- }
- std::wstring adjusted_path(path);
- adjusted_path += L'\\';
- do {
- std::wstring current(adjusted_path);
- current += data.cFileName;
- if (!DeleteFile(current.c_str()))
- return false;
- } while (FindNextFile(handle, &data));
- return true;
-}
-
-// Deletes the cache files stored on |path|, and optionally also attempts to
-// delete the folder itself.
-void DeleteCache(const std::wstring& path, bool remove_folder) {
- DeleteFiles(path.c_str(), L"\\f_*");
- DeleteFiles(path.c_str(), L"\\data_*");
-
- std::wstring index(path);
- file_util::AppendToPath(&index, kIndexName);
- DeleteFile(index.c_str());
-
- if (remove_folder)
- RemoveDirectory(path.c_str());
-}
-
int LowWaterAdjust(int high_water) {
if (high_water < kCleanUpMargin)
return 0;
@@ -149,7 +112,7 @@ class CleanupTask : public Task {
void CleanupTask::Run() {
for (int i = 0; i < kMaxOldFolders; i++) {
std::wstring to_delete = GetPrefixedName(path_, name_, i);
- DeleteCache(to_delete, true);
+ disk_cache::DeleteCache(to_delete, true);
}
}
@@ -180,10 +143,7 @@ bool DelayedCacheCleanup(const std::wstring& full_path) {
return false;
}
- // I don't want to use the shell version of move because if something goes
- // wrong, that version will attempt to move file by file and fail at the end.
- if (!MoveFileEx(full_path.c_str(), to_delete.c_str(), 0)) {
- DWORD error = GetLastError();
+ if (!disk_cache::MoveCache(full_path.c_str(), to_delete.c_str())) {
LOG(ERROR) << "Unable to rename cache folder";
return false;
}
@@ -302,15 +262,7 @@ BackendImpl::~BackendImpl() {
delete timer_;
delete timer_task_;
- while (num_pending_io_) {
- // Asynchronous IO operations may be in flight and the completion may end
- // up calling us back so let's wait for them (we need an alertable wait).
- // The idea is to let other threads do usefull work and at the same time
- // allow more than one IO to finish... 20 mS later, we process all queued
- // APCs and see if we have to repeat the wait.
- Sleep(20);
- SleepEx(0, TRUE);
- }
+ WaitForPendingIO(num_pending_io_);
DCHECK(!num_refs_);
}
@@ -629,10 +581,10 @@ bool BackendImpl::CreateExternalFile(Addr* address) {
continue;
}
std::wstring name = GetFileName(file_address);
- ScopedHandle file(CreateFile(name.c_str(), GENERIC_WRITE | GENERIC_READ,
- FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0,
- NULL));
- if (!file.IsValid())
+ scoped_refptr<disk_cache::File> file(
+ new disk_cache::File(CreateOSFile(name.c_str(), OS_FILE_READ |
+ OS_FILE_WRITE |OS_FILE_SHARE_READ | OS_FILE_CREATE_ALWAYS, NULL)));
+ if (!file->IsValid())
continue;
success = true;
@@ -796,31 +748,20 @@ int BackendImpl::SelfCheck() {
return CheckAllEntries();
}
-
// ------------------------------------------------------------------------
// We just created a new file so we're going to write the header and set the
// file length to include the hash table (zero filled).
-bool BackendImpl::CreateBackingStore(HANDLE file) {
+bool BackendImpl::CreateBackingStore(disk_cache::File* file) {
AdjustMaxCacheSize(0);
IndexHeader header;
header.table_len = DesiredIndexTableLen(max_size_);
- DWORD actual;
- if (!WriteFile(file, &header, sizeof(header), &actual, NULL) ||
- sizeof(header) != actual)
- return false;
-
- LONG size = static_cast<LONG>(GetIndexSize(header.table_len));
-
- if (INVALID_SET_FILE_POINTER == SetFilePointer(file, size, NULL, FILE_BEGIN))
- return false;
-
- if (!SetEndOfFile(file))
+ if (!file->Write(&header, sizeof(header), 0))
return false;
- return true;
+ return file->SetLength(GetIndexSize(header.table_len));
}
bool BackendImpl::InitBackingStore(bool* file_created) {
@@ -830,21 +771,18 @@ bool BackendImpl::InitBackingStore(bool* file_created) {
std::wstring index_name(path_);
file_util::AppendToPath(&index_name, kIndexName);
- HANDLE file = CreateFile(index_name.c_str(), GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, NULL);
+ scoped_refptr<disk_cache::File> file(new disk_cache::File(
+ CreateOSFile(index_name.c_str(), OS_FILE_READ | OS_FILE_WRITE |
+ OS_FILE_SHARE_READ | OS_FILE_OPEN_ALWAYS, file_created)));
- if (INVALID_HANDLE_VALUE == file)
+ if (!file->IsValid())
return false;
bool ret = true;
- if (ERROR_ALREADY_EXISTS != GetLastError()) {
- *file_created = true;
+ if (*file_created)
ret = CreateBackingStore(file);
- } else {
- *file_created = false;
- }
-
- CloseHandle(file);
+
+ file = NULL;
if (!ret)
return false;
@@ -858,21 +796,21 @@ void BackendImpl::AdjustMaxCacheSize(int table_len) {
return;
// The user is not setting the size, let's figure it out.
- ULARGE_INTEGER available, total, free;
- if (!GetDiskFreeSpaceExW(path_.c_str(), &available, &total, &free)) {
+ int64 available = GetFreeDiskSpace(path_);
+ if (available < 0) {
max_size_ = kDefaultCacheSize;
return;
}
// Attempt to use 1% of the disk available for this user.
- available.QuadPart /= 100;
+ available /= 100;
- if (available.QuadPart < static_cast<uint32>(kDefaultCacheSize))
+ if (available < kDefaultCacheSize)
max_size_ = kDefaultCacheSize;
- else if (available.QuadPart > static_cast<uint32>(kint32max))
+ else if (available > kint32max)
max_size_ = kint32max;
else
- max_size_ = static_cast<int32>(available.LowPart);
+ max_size_ = static_cast<int32>(available);
// Let's not use more than the default size while we tune-up the performance
// of bigger caches. TODO(rvargas): remove this limit.
diff --git a/net/disk_cache/backend_impl.h b/net/disk_cache/backend_impl.h
index 602190a..1f1bffd 100644
--- a/net/disk_cache/backend_impl.h
+++ b/net/disk_cache/backend_impl.h
@@ -141,7 +141,7 @@ class BackendImpl : public Backend {
private:
// Creates a new backing file for the cache index.
- bool CreateBackingStore(HANDLE file);
+ bool CreateBackingStore(disk_cache::File* file);
bool InitBackingStore(bool* file_created);
void AdjustMaxCacheSize(int table_len);
diff --git a/net/disk_cache/block_files.cc b/net/disk_cache/block_files.cc
index 93578cf..79be295 100644
--- a/net/disk_cache/block_files.cc
+++ b/net/disk_cache/block_files.cc
@@ -217,11 +217,11 @@ std::wstring BlockFiles::Name(int index) {
bool BlockFiles::CreateBlockFile(int index, FileType file_type, bool force) {
std::wstring name = Name(index);
- DWORD disposition = force ? CREATE_ALWAYS : CREATE_NEW;
+ int flags = force ? OS_FILE_CREATE_ALWAYS : OS_FILE_CREATE;
+ flags |= OS_FILE_WRITE | OS_FILE_SHARE_READ;
- ScopedHandle file(CreateFile(name.c_str(), GENERIC_WRITE, FILE_SHARE_READ,
- NULL, disposition, 0, NULL));
- if (!file.IsValid())
+ scoped_refptr<File> file(new File(CreateOSFile(name.c_str(), flags, NULL)));
+ if (!file->IsValid())
return false;
BlockFileHeader header;
@@ -229,12 +229,7 @@ bool BlockFiles::CreateBlockFile(int index, FileType file_type, bool force) {
header.this_file = static_cast<int16>(index);
DCHECK(index <= kint16max && index >= 0);
- DWORD actual;
- if (!WriteFile(file.Get(), &header, sizeof(header), &actual, NULL) ||
- sizeof(header) != actual)
- return false;
-
- return true;
+ return file->Write(&header, sizeof(header), 0);
}
bool BlockFiles::OpenBlockFile(int index) {
diff --git a/net/disk_cache/cache_util.h b/net/disk_cache/cache_util.h
new file mode 100644
index 0000000..f6815c9
--- /dev/null
+++ b/net/disk_cache/cache_util.h
@@ -0,0 +1,59 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef NET_DISK_CACHE_CACHE_UTIL_H_
+#define NET_DISK_CACHE_CACHE_UTIL_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+
+namespace disk_cache {
+
+// Returns the available disk space on the volume that contains |path|, or -1
+// on failure.
+int64 GetFreeDiskSpace(const std::wstring& path);
+
+// Returns the total physical memory on the system, or -1 on failure.
+int64 GetSystemMemory();
+
+// Moves the cache files from the given path to another location.
+// Returns true if successful, false otherwise.
+bool MoveCache(const std::wstring& from_path, const std::wstring& to_path);
+
+// Deletes the cache files stored on |path|, and optionally also attempts to
+// delete the folder itself.
+void DeleteCache(const std::wstring& path, bool remove_folder);
+
+// Blocks until |num_pending_io| IO operations complete.
+void WaitForPendingIO(int num_pending_io);
+
+} // namespace disk_cache
+
+#endif // NET_DISK_CACHE_CACHE_UTIL_H_
diff --git a/net/disk_cache/cache_util_posix.cc b/net/disk_cache/cache_util_posix.cc
new file mode 100644
index 0000000..10e0b93
--- /dev/null
+++ b/net/disk_cache/cache_util_posix.cc
@@ -0,0 +1,62 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "net/cache_util.h"
+
+#include "base/file_util.h"
+#include "base/logging.h"
+
+namespace disk_cache {
+
+int64 GetFreeDiskSpace(const std::wstring& path) {
+ DLOG(WARNING) << "Not Implemented";
+ return -1;
+}
+
+int64 GetSystemMemory() {
+ // TODO(pinkerton): figure this out for mac/linux
+ return -1;
+}
+
+bool MoveCache(const std::wstring& from_path, const std::wstring& to_path) {
+ // Just use the version from base.
+ return file_util::Move(from_path.c_str(), to_path.c_str());
+}
+
+void DeleteCache(const std::wstring& path, bool remove_folder) {
+ if (remove_folder) {
+ file_util::Delete(path, false);
+ } else {
+ std::wstring name(path);
+ file_util::AppendToPath(name, L"*");
+ file_util::Delete(name, false);
+ }
+}
+
+} // namespace disk_cache
diff --git a/net/disk_cache/cache_util_win.cc b/net/disk_cache/cache_util_win.cc
new file mode 100644
index 0000000..a66f2c3
--- /dev/null
+++ b/net/disk_cache/cache_util_win.cc
@@ -0,0 +1,116 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "net/disk_cache/cache_util.h"
+
+#include <windows.h>
+
+#include "base/scoped_handle.h"
+#include "base/file_util.h"
+
+namespace disk_cache {
+
+int64 GetFreeDiskSpace(const std::wstring& path) {
+ ULARGE_INTEGER available, total, free;
+ if (!GetDiskFreeSpaceExW(path.c_str(), &available, &total, &free)) {
+ return -1;
+ }
+ int64 rv = static_cast<int64>(available.QuadPart);
+ if (rv < 0)
+ rv = kint64max;
+ return rv;
+}
+
+int64 GetSystemMemory() {
+ MEMORYSTATUSEX memory_info;
+ memory_info.dwLength = sizeof(memory_info);
+ if (!GlobalMemoryStatusEx(&memory_info)) {
+ return -1;
+ }
+
+ int64 rv = static_cast<int64>(memory_info.ullTotalPhys);
+ if (rv < 0)
+ rv = kint64max;
+ return rv;
+}
+
+bool MoveCache(const std::wstring& from_path, const std::wstring& to_path) {
+ // I don't want to use the shell version of move because if something goes
+ // wrong, that version will attempt to move file by file and fail at the end.
+ return MoveFileEx(from_path.c_str(), to_path.c_str(), 0) != FALSE;
+}
+
+// Deletes all the files on path that match search_name pattern.
+// Do not call this function with "*" as search_name.
+bool DeleteFiles(const wchar_t* path, const wchar_t* search_name) {
+ std::wstring name(path);
+ file_util::AppendToPath(&name, search_name);
+
+ WIN32_FIND_DATA data;
+ ScopedFindFileHandle handle(FindFirstFile(name.c_str(), &data));
+ if (!handle.IsValid()) {
+ DWORD error = GetLastError();
+ return ERROR_FILE_NOT_FOUND == error;
+ }
+ std::wstring adjusted_path(path);
+ adjusted_path += L'\\';
+ do {
+ std::wstring current(adjusted_path);
+ current += data.cFileName;
+ if (!DeleteFile(current.c_str()))
+ return false;
+ } while (FindNextFile(handle, &data));
+ return true;
+}
+
+void DeleteCache(const std::wstring& path, bool remove_folder) {
+ DeleteFiles(path.c_str(), L"f_*");
+ DeleteFiles(path.c_str(), L"data_*");
+
+ std::wstring index(path);
+ file_util::AppendToPath(&index, L"index");
+ DeleteFile(index.c_str());
+
+ if (remove_folder)
+ RemoveDirectory(path.c_str());
+}
+
+void WaitForPendingIO(int num_pending_io) {
+ while (num_pending_io) {
+ // Asynchronous IO operations may be in flight and the completion may end
+ // up calling us back so let's wait for them (we need an alertable wait).
+ // The idea is to let other threads do usefull work and at the same time
+ // allow more than one IO to finish... 20 mS later, we process all queued
+ // APCs and see if we have to repeat the wait.
+ Sleep(20);
+ SleepEx(0, TRUE);
+ }
+}
+
+} // namespace disk_cache
diff --git a/net/disk_cache/file.cc b/net/disk_cache/file.cc
index 36b023b..41ed2b7 100644
--- a/net/disk_cache/file.cc
+++ b/net/disk_cache/file.cc
@@ -113,26 +113,33 @@ void CALLBACK IoCompletion(DWORD error, DWORD actual_bytes,
}
}
+File::File(OSFile file)
+ : init_(true), mixed_(true), os_file_(INVALID_HANDLE_VALUE),
+ sync_os_file_(file) {
+}
+
bool File::Init(const std::wstring name) {
DCHECK(!init_);
if (init_)
return false;
- handle_ = CreateFile(name.c_str(), GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
- FILE_FLAG_OVERLAPPED, NULL);
+ os_file_ = CreateFile(name.c_str(), GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
+ FILE_FLAG_OVERLAPPED, NULL);
- if (INVALID_HANDLE_VALUE == handle_)
+ if (INVALID_HANDLE_VALUE == os_file_)
return false;
init_ = true;
if (mixed_) {
- sync_handle_ = CreateFile(name.c_str(), GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
- OPEN_EXISTING, 0, NULL);
+ sync_os_file_ = CreateFile(name.c_str(), GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+ OPEN_EXISTING, 0, NULL);
- if (INVALID_HANDLE_VALUE == sync_handle_)
+ if (INVALID_HANDLE_VALUE == sync_os_file_)
return false;
+ } else {
+ sync_os_file_ = INVALID_HANDLE_VALUE;
}
return true;
@@ -142,39 +149,54 @@ File::~File() {
if (!init_)
return;
- CloseHandle(handle_);
- if (mixed_ && INVALID_HANDLE_VALUE != sync_handle_)
- CloseHandle(sync_handle_);
+ if (INVALID_HANDLE_VALUE != os_file_)
+ CloseHandle(os_file_);
+ if (mixed_ && INVALID_HANDLE_VALUE != sync_os_file_)
+ CloseHandle(sync_os_file_);
+}
+
+OSFile File::os_file() const {
+ DCHECK(init_);
+ return (INVALID_HANDLE_VALUE == os_file_) ? sync_os_file_ : os_file_;
+}
+
+bool File::IsValid() const {
+ if (!init_)
+ return false;
+ return (INVALID_HANDLE_VALUE != os_file_ ||
+ INVALID_HANDLE_VALUE != sync_os_file_);
}
bool File::Read(void* buffer, size_t buffer_len, size_t offset) {
+ DCHECK(init_);
if (!mixed_ || buffer_len > ULONG_MAX || offset > LONG_MAX)
return false;
- DWORD ret = SetFilePointer(sync_handle_, static_cast<LONG>(offset), NULL,
+ DWORD ret = SetFilePointer(sync_os_file_, static_cast<LONG>(offset), NULL,
FILE_BEGIN);
if (INVALID_SET_FILE_POINTER == ret)
return false;
DWORD actual;
DWORD size = static_cast<DWORD>(buffer_len);
- if (!ReadFile(sync_handle_, buffer, size, &actual, NULL))
+ if (!ReadFile(sync_os_file_, buffer, size, &actual, NULL))
return false;
return actual == size;
}
bool File::Write(const void* buffer, size_t buffer_len, size_t offset) {
+ DCHECK(init_);
if (!mixed_ || buffer_len > ULONG_MAX || offset > ULONG_MAX)
return false;
- DWORD ret = SetFilePointer(sync_handle_, static_cast<LONG>(offset), NULL,
+ DWORD ret = SetFilePointer(sync_os_file_, static_cast<LONG>(offset), NULL,
FILE_BEGIN);
if (INVALID_SET_FILE_POINTER == ret)
return false;
DWORD actual;
DWORD size = static_cast<DWORD>(buffer_len);
- if (!WriteFile(sync_handle_, buffer, size, &actual, NULL))
+ if (!WriteFile(sync_os_file_, buffer, size, &actual, NULL))
return false;
return actual == size;
}
@@ -184,6 +206,7 @@ bool File::Write(const void* buffer, size_t buffer_len, size_t offset) {
// closed while the IO is in flight).
bool File::Read(void* buffer, size_t buffer_len, size_t offset,
FileIOCallback* callback, bool* completed) {
+ DCHECK(init_);
if (buffer_len > ULONG_MAX || offset > ULONG_MAX)
return false;
@@ -198,7 +221,7 @@ bool File::Read(void* buffer, size_t buffer_len, size_t offset,
DWORD size = static_cast<DWORD>(buffer_len);
AddRef();
- if (!ReadFileEx(handle_, buffer, size, &data->overlapped, &IoCompletion)) {
+ if (!ReadFileEx(os_file_, buffer, size, &data->overlapped, &IoCompletion)) {
Release();
delete data;
return false;
@@ -231,15 +254,18 @@ bool File::Read(void* buffer, size_t buffer_len, size_t offset,
bool File::Write(const void* buffer, size_t buffer_len, size_t offset,
FileIOCallback* callback, bool* completed) {
+ DCHECK(init_);
return AsyncWrite(buffer, buffer_len, offset, true, callback, completed);
}
bool File::PostWrite(const void* buffer, size_t buffer_len, size_t offset) {
+ DCHECK(init_);
return AsyncWrite(buffer, buffer_len, offset, false, NULL, NULL);
}
bool File::AsyncWrite(const void* buffer, size_t buffer_len, size_t offset,
bool notify, FileIOCallback* callback, bool* completed) {
+ DCHECK(init_);
if (buffer_len > ULONG_MAX || offset > ULONG_MAX)
return false;
@@ -259,7 +285,7 @@ bool File::AsyncWrite(const void* buffer, size_t buffer_len, size_t offset,
DWORD size = static_cast<DWORD>(buffer_len);
AddRef();
- if (!WriteFileEx(handle_, buffer, size, &data->overlapped, &IoCompletion)) {
+ if (!WriteFileEx(os_file_, buffer, size, &data->overlapped, &IoCompletion)) {
Release();
delete data;
return false;
@@ -289,20 +315,23 @@ bool File::AsyncWrite(const void* buffer, size_t buffer_len, size_t offset,
}
bool File::SetLength(size_t length) {
+ DCHECK(init_);
if (length > ULONG_MAX)
return false;
DWORD size = static_cast<DWORD>(length);
- if (INVALID_SET_FILE_POINTER == SetFilePointer(handle_, size, NULL,
- FILE_BEGIN))
+ HANDLE file = os_file();
+ if (INVALID_SET_FILE_POINTER == SetFilePointer(file, size, NULL, FILE_BEGIN))
return false;
- return TRUE == SetEndOfFile(handle_);
+ return TRUE == SetEndOfFile(file);
}
size_t File::GetLength() {
+ DCHECK(init_);
LARGE_INTEGER size;
- if (!GetFileSizeEx(handle_, &size))
+ HANDLE file = os_file();
+ if (!GetFileSizeEx(file, &size))
return 0;
if (size.HighPart)
return ULONG_MAX;
diff --git a/net/disk_cache/file.h b/net/disk_cache/file.h
index db42026..f692b01 100644
--- a/net/disk_cache/file.h
+++ b/net/disk_cache/file.h
@@ -33,6 +33,7 @@
#define NET_DISK_CACHE_FILE_H__
#include "base/ref_counted.h"
+#include "net/disk_cache/os_file.h"
namespace disk_cache {
@@ -52,19 +53,20 @@ class File : public base::RefCounted<File> {
// mixed_mode set to true enables regular synchronous operations for the file.
explicit File(bool mixed_mode) : init_(false), mixed_(mixed_mode) {}
+ // Initializes the object to use the passed in file instead of opening it with
+ // the Init() call. No asynchronous operations can be performed with this
+ // object.
+ explicit File(OSFile file);
+
// Initializes the object to point to a given file. The file must aready exist
// on disk, and allow shared read and write.
bool Init(const std::wstring name);
-#ifdef WIN32
- HANDLE handle() const {
- return handle_;
- }
-#else
- int file_descriptor() const {
- return file_descriptor_;
- }
-#endif
+ // Returns the handle or file descriptor.
+ OSFile os_file() const;
+
+ // Returns true if the file was opened properly.
+ bool IsValid() const;
// Performs synchronous IO.
bool Read(void* buffer, size_t buffer_len, size_t offset);
@@ -97,14 +99,10 @@ class File : public base::RefCounted<File> {
private:
bool init_;
bool mixed_;
-#ifdef WIN32
- HANDLE handle_; // Regular, asynchronous IO handle.
- HANDLE sync_handle_; // Synchronous IO hanlde.
-#else
- int file_descriptor_;
-#endif
-
- DISALLOW_EVIL_CONSTRUCTORS(File);
+ OSFile os_file_; // Regular, asynchronous IO handle.
+ OSFile sync_os_file_; // Synchronous IO hanlde.
+
+ DISALLOW_COPY_AND_ASSIGN(File);
};
} // namespace disk_cache
diff --git a/net/disk_cache/file_block.h b/net/disk_cache/file_block.h
index 50574b3..9b2973d 100644
--- a/net/disk_cache/file_block.h
+++ b/net/disk_cache/file_block.h
@@ -48,7 +48,7 @@ class FileBlock {
virtual size_t size() const = 0;
// Returns the file offset of this block.
- virtual DWORD offset() const = 0;
+ virtual int offset() const = 0;
};
} // namespace disk_cache
diff --git a/net/disk_cache/mapped_file.cc b/net/disk_cache/mapped_file.cc
index ee459da..c963063 100644
--- a/net/disk_cache/mapped_file.cc
+++ b/net/disk_cache/mapped_file.cc
@@ -40,7 +40,7 @@ void* MappedFile::Init(const std::wstring name, size_t size) {
buffer_ = NULL;
init_ = true;
- section_ = CreateFileMapping(handle(), NULL, PAGE_READWRITE, 0,
+ section_ = CreateFileMapping(os_file(), NULL, PAGE_READWRITE, 0,
static_cast<DWORD>(size), NULL);
if (!section_)
return NULL;
diff --git a/net/disk_cache/mapped_file.h b/net/disk_cache/mapped_file.h
index cb2da0c..693ea90 100644
--- a/net/disk_cache/mapped_file.h
+++ b/net/disk_cache/mapped_file.h
@@ -65,7 +65,9 @@ class MappedFile : public File {
private:
bool init_;
+#if defined(OS_WIN)
HANDLE section_;
+#endif
void* buffer_; // Address of the memory mapped buffer.
size_t view_size_; // Size of the memory pointed by buffer_.
diff --git a/net/disk_cache/mem_backend_impl.cc b/net/disk_cache/mem_backend_impl.cc
index 10aadb8..fa5018b 100644
--- a/net/disk_cache/mem_backend_impl.cc
+++ b/net/disk_cache/mem_backend_impl.cc
@@ -29,6 +29,7 @@
#include "net/disk_cache/mem_backend_impl.h"
+#include "net/disk_cache/cache_util.h"
#include "net/disk_cache/mem_entry_impl.h"
namespace {
@@ -64,21 +65,20 @@ bool MemBackendImpl::Init() {
if (max_size_)
return true;
- MEMORYSTATUSEX memory_info;
- memory_info.dwLength = sizeof(memory_info);
- if (!GlobalMemoryStatusEx(&memory_info)) {
+ int64 total_memory = GetSystemMemory();
+
+ if (total_memory < 0) {
max_size_ = kDefaultCacheSize;
return true;
}
// We want to use up to 2% of the computer's memory, with a limit of 50 MB,
// reached on systemd with more than 2.5 GB of RAM.
- memory_info.ullTotalPhys = memory_info.ullTotalPhys * 2 / 100;
- if (memory_info.ullTotalPhys >
- static_cast<unsigned int>(kDefaultCacheSize * 5))
+ total_memory = total_memory * 2 / 100;
+ if (total_memory > kDefaultCacheSize * 5)
max_size_ = kDefaultCacheSize * 5;
else
- max_size_ = static_cast<int>(memory_info.ullTotalPhys);
+ max_size_ = static_cast<int32>(total_memory);
return true;
}
diff --git a/net/disk_cache/mem_backend_impl.h b/net/disk_cache/mem_backend_impl.h
index 0804ad0..36adae0 100644
--- a/net/disk_cache/mem_backend_impl.h
+++ b/net/disk_cache/mem_backend_impl.h
@@ -32,7 +32,7 @@
#ifndef NET_DISK_CACHE_MEM_BACKEND_IMPL_H__
#define NET_DISK_CACHE_MEM_BACKEND_IMPL_H__
-#include <hash_map>
+#include "base/hash_tables.h"
#include "net/disk_cache/disk_cache.h"
#include "net/disk_cache/mem_rankings.h"
@@ -89,7 +89,7 @@ class MemBackendImpl : public Backend {
void AddStorageSize(int32 bytes);
void SubstractStorageSize(int32 bytes);
- typedef stdext::hash_map<std::string, MemEntryImpl*> EntryMap;
+ typedef base::hash_map<std::string, MemEntryImpl*> EntryMap;
EntryMap entries_;
MemRankings rankings_; // Rankings to be able to trim the cache.
diff --git a/net/disk_cache/os_file.h b/net/disk_cache/os_file.h
new file mode 100644
index 0000000..4409a02
--- /dev/null
+++ b/net/disk_cache/os_file.h
@@ -0,0 +1,64 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef NET_DISK_CACHE_OS_FILE_H_
+#define NET_DISK_CACHE_OS_FILE_H_
+
+#include <string>
+
+#include "build/build_config.h"
+
+namespace disk_cache {
+
+#if defined(OS_WIN)
+#include <windows.h>
+typedef HANDLE OSFile;
+#elif defined(OS_POSIX)
+typedef int OSFile;
+#endif
+
+enum OSFileFlags {
+ OS_FILE_OPEN = 1,
+ OS_FILE_CREATE = 2,
+ OS_FILE_OPEN_ALWAYS = 4, // May create a new file.
+ OS_FILE_CREATE_ALWAYS = 8, // May overwrite an old file.
+ OS_FILE_READ = 16,
+ OS_FILE_WRITE = 32,
+ OS_FILE_SHARE_READ = 64,
+ OS_FILE_SHARE_WRITE = 128
+};
+
+// Creates or open the given file. If OS_FILE_OPEN_ALWAYS is used, and |created|
+// is provided, |created| will be set to true if the file was created or to
+// false in case the file was just opened.
+OSFile CreateOSFile(const std::wstring& name, int flags, bool* created);
+
+} // namespace disk_cache
+
+#endif // NET_DISK_CACHE_OS_FILE_H_
diff --git a/net/disk_cache/os_file_posix.cc b/net/disk_cache/os_file_posix.cc
new file mode 100644
index 0000000..4ccf4e3
--- /dev/null
+++ b/net/disk_cache/os_file_posix.cc
@@ -0,0 +1,41 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "net/disk_cache/os_file.h"
+
+#include "base/notimplemented.h"
+
+namespace disk_cache {
+
+OSFile CreateOSFile(const std::wstring& name, int flags, bool* created) {
+ NOTIMPLEMENTED();
+ return 0;
+}
+
+} // namespace disk_cache
diff --git a/net/disk_cache/os_file_win.cc b/net/disk_cache/os_file_win.cc
new file mode 100644
index 0000000..5276b24
--- /dev/null
+++ b/net/disk_cache/os_file_win.cc
@@ -0,0 +1,81 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "net/disk_cache/os_file.h"
+
+#include "base/logging.h"
+
+namespace disk_cache {
+
+OSFile CreateOSFile(const std::wstring& name, int flags, bool* created) {
+ DWORD disposition = 0;
+
+ if (flags & OS_FILE_OPEN)
+ disposition = OPEN_EXISTING;
+
+ if (flags & OS_FILE_CREATE) {
+ DCHECK(!disposition);
+ disposition = CREATE_NEW;
+ }
+
+ if (flags & OS_FILE_OPEN_ALWAYS) {
+ DCHECK(!disposition);
+ disposition = OPEN_ALWAYS;
+ }
+
+ if (flags & OS_FILE_CREATE_ALWAYS) {
+ DCHECK(!disposition);
+ disposition = CREATE_ALWAYS;
+ }
+
+ if (!disposition) {
+ NOTREACHED();
+ return NULL;
+ }
+
+ DWORD access = (flags & OS_FILE_READ) ? GENERIC_READ : 0;
+ if (flags & OS_FILE_WRITE)
+ access |= GENERIC_WRITE;
+
+ DWORD sharing = (flags & OS_FILE_SHARE_READ) ? FILE_SHARE_READ : 0;
+ if (flags & OS_FILE_SHARE_WRITE)
+ access |= FILE_SHARE_WRITE;
+
+ HANDLE file = CreateFile(name.c_str(), access, sharing, NULL, disposition, 0,
+ NULL);
+
+ if ((flags & OS_FILE_OPEN_ALWAYS) && created &&
+ INVALID_HANDLE_VALUE != file) {
+ *created = (ERROR_ALREADY_EXISTS != GetLastError());
+ }
+
+ return file;
+}
+
+} // namespace disk_cache
diff --git a/net/disk_cache/rankings.h b/net/disk_cache/rankings.h
index 898092d..6e7f750 100644
--- a/net/disk_cache/rankings.h
+++ b/net/disk_cache/rankings.h
@@ -90,7 +90,7 @@ class Rankings {
void reset(CacheRankingsBlock* p = NULL) {
if (p != get())
rankings_->FreeRankingsBlock(get());
- scoped_ptr::reset(p);
+ scoped_ptr<CacheRankingsBlock>::reset(p);
}
private:
diff --git a/net/disk_cache/storage_block-inl.h b/net/disk_cache/storage_block-inl.h
index 35ba95b..08ade9a 100644
--- a/net/disk_cache/storage_block-inl.h
+++ b/net/disk_cache/storage_block-inl.h
@@ -62,7 +62,7 @@ template<typename T> size_t StorageBlock<T>::size() const {
return address_.num_blocks() * sizeof(*data_);
}
-template<typename T> DWORD StorageBlock<T>::offset() const {
+template<typename T> int StorageBlock<T>::offset() const {
return address_.start_block() * address_.BlockSize();
}
diff --git a/net/disk_cache/storage_block.h b/net/disk_cache/storage_block.h
index 7c100fd..6873933 100644
--- a/net/disk_cache/storage_block.h
+++ b/net/disk_cache/storage_block.h
@@ -63,7 +63,7 @@ class StorageBlock : public FileBlock {
// FileBlock interface.
virtual void* buffer() const;
virtual size_t size() const;
- virtual DWORD offset() const;
+ virtual int offset() const;
// Allows the overide of dummy values passed on the constructor.
bool LazyInit(MappedFile* file, Addr address);