diff options
author | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-13 18:30:22 +0000 |
---|---|---|
committer | rvargas@google.com <rvargas@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-13 18:30:22 +0000 |
commit | 408d35f5f5c316b2f8df12be606a8ff8921ba5ca (patch) | |
tree | 44323772354a63ac53bb48997523abf37707ef1e /net/disk_cache | |
parent | 9fa3c108d312d6664c51f02f203bc60fd4750156 (diff) | |
download | chromium_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.cc | 112 | ||||
-rw-r--r-- | net/disk_cache/backend_impl.h | 2 | ||||
-rw-r--r-- | net/disk_cache/block_files.cc | 15 | ||||
-rw-r--r-- | net/disk_cache/cache_util.h | 59 | ||||
-rw-r--r-- | net/disk_cache/cache_util_posix.cc | 62 | ||||
-rw-r--r-- | net/disk_cache/cache_util_win.cc | 116 | ||||
-rw-r--r-- | net/disk_cache/file.cc | 71 | ||||
-rw-r--r-- | net/disk_cache/file.h | 32 | ||||
-rw-r--r-- | net/disk_cache/file_block.h | 2 | ||||
-rw-r--r-- | net/disk_cache/mapped_file.cc | 2 | ||||
-rw-r--r-- | net/disk_cache/mapped_file.h | 2 | ||||
-rw-r--r-- | net/disk_cache/mem_backend_impl.cc | 14 | ||||
-rw-r--r-- | net/disk_cache/mem_backend_impl.h | 4 | ||||
-rw-r--r-- | net/disk_cache/os_file.h | 64 | ||||
-rw-r--r-- | net/disk_cache/os_file_posix.cc | 41 | ||||
-rw-r--r-- | net/disk_cache/os_file_win.cc | 81 | ||||
-rw-r--r-- | net/disk_cache/rankings.h | 2 | ||||
-rw-r--r-- | net/disk_cache/storage_block-inl.h | 2 | ||||
-rw-r--r-- | net/disk_cache/storage_block.h | 2 |
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); |