13f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/file_path.h" 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/logging.h" 7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/scoped_ptr.h" 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/message_loop.h" 93345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h" 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/string_util.h" 113f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/threading/thread.h" 123f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen#include "base/win/scoped_handle.h" 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "googleurl/src/gurl.h" 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/base/io_buffer.h" 1572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "net/base/net_errors.h" 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/test_completion_callback.h" 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/disk_cache/backend_impl.h" 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/disk_cache/entry_impl.h" 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_cache.h" 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_response_headers.h" 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/http_response_info.h" 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/tools/dump_cache/cache_dumper.h" 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace { 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst wchar_t kPipePrefix[] = L"\\\\.\\pipe\\dump_cache_"; 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst int kChannelSize = 64 * 1024; 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst int kNumStreams = 4; 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Simple macro to print out formatted debug messages. It is similar to a DLOG 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// except that it doesn't include a header. 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifdef NDEBUG 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define DEBUGMSG(...) {} 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#else 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define DEBUGMSG(...) { printf(__VA_ARGS__); } 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#endif 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottHANDLE OpenServer(const std::wstring& pipe_number) { 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::wstring pipe_name(kPipePrefix); 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pipe_name.append(pipe_number); 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return CreateFile(pipe_name.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This is the basic message to use between the two processes. It is intended 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// to transmit a single action (like "get the key name for entry xx"), with up 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// to 5 32-bit arguments and 4 64-bit arguments. After this structure, the rest 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// of the message has |buffer_bytes| of length with the actual data. 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct Message { 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int32 command; 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int32 result; 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int32 buffer_bytes; 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int32 arg1; 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int32 arg2; 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int32 arg3; 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int32 arg4; 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int32 arg5; 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int64 long_arg1; 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int64 long_arg2; 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int64 long_arg3; 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int64 long_arg4; 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Message() { 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memset(this, 0, sizeof(*this)); 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Message& operator= (const Message& other) { 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memcpy(this, &other, sizeof(*this)); 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return *this; 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottconst int kBufferSize = kChannelSize - sizeof(Message); 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstruct IoBuffer { 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Message msg; 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott char buffer[kBufferSize]; 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottCOMPILE_ASSERT(sizeof(IoBuffer) == kChannelSize, invalid_io_buffer); 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The list of commands. 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Currently, there is support for working ONLY with one entry at a time. 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottenum { 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Get the entry from list |arg1| that follows |long_arg1|. 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The result is placed on |long_arg1| (closes the previous one). 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott GET_NEXT_ENTRY = 1, 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Get the entry from list |arg1| that precedes |long_arg1|. 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The result is placed on |long_arg1| (closes the previous one). 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott GET_PREV_ENTRY, 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Closes the entry |long_arg1|. 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CLOSE_ENTRY, 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Get the key of the entry |long_arg1|. 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott GET_KEY, 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Get last used (long_arg2) and last modified (long_arg3) times for the 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // entry at |long_arg1|. 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott GET_USE_TIMES, 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns on |arg2| the data size in bytes if the stream |arg1| of entry at 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // |long_arg1|. 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott GET_DATA_SIZE, 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Returns |arg2| bytes of the stream |arg1| for the entry at |long_arg1|, 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // starting at offset |arg3|. 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott READ_DATA, 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // End processing requests. 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott QUIT 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The list of return codes. 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottenum { 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott RESULT_OK = 0, 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott RESULT_UNKNOWN_COMMAND, 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott RESULT_INVALID_PARAMETER, 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RESULT_NAME_OVERFLOW, 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RESULT_PENDING // This error code is NOT expected by the master process. 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// ----------------------------------------------------------------------- 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass BaseSM : public MessageLoopForIO::IOHandler { 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch explicit BaseSM(HANDLE channel); 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual ~BaseSM(); 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott protected: 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool SendMsg(const Message& msg); 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool ReceiveMsg(); 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool ConnectChannel(); 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool IsPending(); 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MessageLoopForIO::IOContext in_context_; 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MessageLoopForIO::IOContext out_context_; 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott disk_cache::EntryImpl* entry_; 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott HANDLE channel_; 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int state_; 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int pending_count_; 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_array<char> in_buffer_; 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_array<char> out_buffer_; 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott IoBuffer* input_; 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott IoBuffer* output_; 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Thread cache_thread_; 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DISALLOW_COPY_AND_ASSIGN(BaseSM); 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottBaseSM::BaseSM(HANDLE channel) 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : entry_(NULL), channel_(channel), state_(0), pending_count_(0), 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cache_thread_("cache") { 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott in_buffer_.reset(new char[kChannelSize]); 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott out_buffer_.reset(new char[kChannelSize]); 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott input_ = reinterpret_cast<IoBuffer*>(in_buffer_.get()); 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott output_ = reinterpret_cast<IoBuffer*>(out_buffer_.get()); 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memset(&in_context_, 0, sizeof(in_context_)); 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memset(&out_context_, 0, sizeof(out_context_)); 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott in_context_.handler = this; 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott out_context_.handler = this; 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MessageLoopForIO::current()->RegisterIOHandler(channel_, this); 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CHECK(cache_thread_.StartWithOptions( 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::Thread::Options(MessageLoop::TYPE_IO, 0))); 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottBaseSM::~BaseSM() { 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (entry_) 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott entry_->Close(); 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool BaseSM::SendMsg(const Message& msg) { 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Only one command will be in-flight at a time. Let's start the Read IO here 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // when we know that it will be pending. 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!ReceiveMsg()) 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott output_->msg = msg; 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD written; 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!WriteFile(channel_, output_, sizeof(msg) + msg.buffer_bytes, &written, 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott &out_context_.overlapped)) { 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ERROR_IO_PENDING != GetLastError()) 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pending_count_++; 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool BaseSM::ReceiveMsg() { 182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD read; 183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!ReadFile(channel_, input_, kChannelSize, &read, 184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott &in_context_.overlapped)) { 185c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ERROR_IO_PENDING != GetLastError()) 186c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 187c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 188c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pending_count_++; 189c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 190c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 191c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 192c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool BaseSM::ConnectChannel() { 193c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!ConnectNamedPipe(channel_, &in_context_.overlapped)) { 194c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD error = GetLastError(); 195c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ERROR_PIPE_CONNECTED == error) 196c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 197c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // By returning true in case of a generic error, we allow the operation to 198c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // fail while sending the first message. 199c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ERROR_IO_PENDING != error) 200c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 201c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 202c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pending_count_++; 203c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool BaseSM::IsPending() { 207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return pending_count_ != 0; 208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// ----------------------------------------------------------------------- 211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MasterSM : public BaseSM { 213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch MasterSM(const std::wstring& path, HANDLE channel, bool dump_to_disk) 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : BaseSM(channel), path_(path), dump_to_disk_(dump_to_disk), 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ALLOW_THIS_IN_INITIALIZER_LIST( 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch create_callback_(this, &MasterSM::DoCreateEntryComplete)), 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ALLOW_THIS_IN_INITIALIZER_LIST( 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch write_callback_(this, &MasterSM::DoReadDataComplete)) { 220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual ~MasterSM() { 222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott delete writer_; 223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool DoInit(); 226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void OnIOCompleted(MessageLoopForIO::IOContext* context, 227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD bytes_transfered, DWORD error); 228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 230c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott enum { 231c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MASTER_INITIAL = 0, 232c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MASTER_CONNECT, 233c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MASTER_GET_ENTRY, 234c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MASTER_GET_NEXT_ENTRY, 235c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MASTER_GET_KEY, 236c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MASTER_GET_USE_TIMES, 237c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MASTER_GET_DATA_SIZE, 238c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MASTER_READ_DATA, 239c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MASTER_END 240c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 241c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 242c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void SendGetPrevEntry(); 243c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void DoGetEntry(); 244c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void DoGetKey(int bytes_read); 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void DoCreateEntryComplete(int result); 246c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void DoGetUseTimes(); 247c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void SendGetDataSize(); 248c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void DoGetDataSize(); 249c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void CloseEntry(); 250c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void SendReadData(); 251c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void DoReadData(int bytes_read); 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void DoReadDataComplete(int ret); 253c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void SendQuit(); 254c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void DoEnd(); 255c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Fail(); 256c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 257c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::Time last_used_; 258c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott base::Time last_modified_; 259c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int64 remote_entry_; 260c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int stream_; 261c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int bytes_remaining_; 262c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int offset_; 263c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int copied_entries_; 264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int read_size_; 265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch scoped_ptr<disk_cache::Backend> cache_; 266c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CacheDumpWriter* writer_; 267c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const std::wstring& path_; 268c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool dump_to_disk_; 269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::CompletionCallbackImpl<MasterSM> create_callback_; 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::CompletionCallbackImpl<MasterSM> write_callback_; 271c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 272c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 273c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MasterSM::OnIOCompleted(MessageLoopForIO::IOContext* context, 274c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD bytes_transfered, DWORD error) { 275c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pending_count_--; 276c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (context == &out_context_) { 277c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!error) 278c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 279c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return Fail(); 280c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 281c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 282c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int bytes_read = static_cast<int>(bytes_transfered); 283c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (bytes_read < sizeof(Message) && state_ != MASTER_END && 284c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott state_ != MASTER_CONNECT) { 285c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott printf("Communication breakdown\n"); 286c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return Fail(); 287c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 288c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 289c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott switch (state_) { 290c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case MASTER_CONNECT: 291c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SendGetPrevEntry(); 292c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 293c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case MASTER_GET_ENTRY: 294c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DoGetEntry(); 295c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 296c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case MASTER_GET_KEY: 297c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DoGetKey(bytes_read); 298c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 299c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case MASTER_GET_USE_TIMES: 300c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DoGetUseTimes(); 301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 302c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case MASTER_GET_DATA_SIZE: 303c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DoGetDataSize(); 304c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 305c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case MASTER_READ_DATA: 306c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DoReadData(bytes_read); 307c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 308c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case MASTER_END: 309c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!IsPending()) 310c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DoEnd(); 311c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 312c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott default: 313c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NOTREACHED(); 314c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 315c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 316c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 317c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 318c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool MasterSM::DoInit() { 319c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DEBUGMSG("Master DoInit\n"); 320c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(state_ == MASTER_INITIAL); 321c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 322c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (dump_to_disk_) { 323c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott writer_ = new DiskDumper(path_); 324c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch disk_cache::Backend* cache; 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback cb; 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = disk_cache::CreateCacheBackend(net::DISK_CACHE, 328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath::FromWStringHack(path_), 0, 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false, 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cache_thread_.message_loop_proxy(), 3313f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen NULL, &cache, &cb); 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (cb.GetResult(rv) != net::OK) { 333c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott printf("Unable to initialize new files\n"); 334c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 335c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cache_.reset(cache); 337c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott writer_ = new CacheDumper(cache_.get()); 338c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 339c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!writer_) 340c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return false; 341c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 342c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott copied_entries_ = 0; 343c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott remote_entry_ = 0; 344c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 345c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (ConnectChannel()) { 346c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SendGetPrevEntry(); 347c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // If we don't have pending operations we couldn't connect. 348c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return IsPending(); 349c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 350c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 351c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott state_ = MASTER_CONNECT; 352c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return true; 353c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 354c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 355c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MasterSM::SendGetPrevEntry() { 356c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DEBUGMSG("Master SendGetPrevEntry\n"); 357c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott state_ = MASTER_GET_ENTRY; 358c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Message msg; 359c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.command = GET_PREV_ENTRY; 360c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.long_arg1 = remote_entry_; 361c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SendMsg(msg); 362c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 363c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 364c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MasterSM::DoGetEntry() { 365c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DEBUGMSG("Master DoGetEntry\n"); 366c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(state_ == MASTER_GET_ENTRY); 367c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(input_->msg.command == GET_PREV_ENTRY); 368c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (input_->msg.result != RESULT_OK) 369c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return Fail(); 370c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 371c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!input_->msg.long_arg1) { 372c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott printf("Done: %d entries copied over.\n", copied_entries_); 373c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return SendQuit(); 374c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 375c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott remote_entry_ = input_->msg.long_arg1; 376c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott state_ = MASTER_GET_KEY; 377c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Message msg; 378c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.command = GET_KEY; 379c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.long_arg1 = remote_entry_; 380c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SendMsg(msg); 381c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 382c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 383c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MasterSM::DoGetKey(int bytes_read) { 384c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DEBUGMSG("Master DoGetKey\n"); 385c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(state_ == MASTER_GET_KEY); 386c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(input_->msg.command == GET_KEY); 387c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (input_->msg.result == RESULT_NAME_OVERFLOW) { 388c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The key is too long. Just move on. 389c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott printf("Skipping entry (name too long)\n"); 390c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return SendGetPrevEntry(); 391c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 392c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 393c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (input_->msg.result != RESULT_OK) 394c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return Fail(); 395c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 396c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string key(input_->buffer); 397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(key.size() == static_cast<size_t>(input_->msg.buffer_bytes - 1)); 398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = writer_->CreateEntry(key, 400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch reinterpret_cast<disk_cache::Entry**>(&entry_), 401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &create_callback_); 402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rv != net::ERR_IO_PENDING) 404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DoCreateEntryComplete(rv); 405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 406c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid MasterSM::DoCreateEntryComplete(int result) { 408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string key(input_->buffer); 409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (result != net::OK) { 410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch printf("Skipping entry \"%s\": %d\n", key.c_str(), GetLastError()); 411c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return SendGetPrevEntry(); 412c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 413c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 414c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (key.size() >= 64) { 415c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott key[60] = '.'; 416c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott key[61] = '.'; 417c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott key[62] = '.'; 418c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott key[63] = '\0'; 419c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 420c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DEBUGMSG("Entry \"%s\" created\n", key.c_str()); 421c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott state_ = MASTER_GET_USE_TIMES; 422c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Message msg; 423c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.command = GET_USE_TIMES; 424c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.long_arg1 = remote_entry_; 425c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SendMsg(msg); 426c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 427c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 428c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MasterSM::DoGetUseTimes() { 429c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DEBUGMSG("Master DoGetUseTimes\n"); 430c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(state_ == MASTER_GET_USE_TIMES); 431c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(input_->msg.command == GET_USE_TIMES); 432c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (input_->msg.result != RESULT_OK) 433c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return Fail(); 434c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 435c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott last_used_ = base::Time::FromInternalValue(input_->msg.long_arg2); 436c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott last_modified_ = base::Time::FromInternalValue(input_->msg.long_arg3); 437c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stream_ = 0; 438c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SendGetDataSize(); 439c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 440c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 441c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MasterSM::SendGetDataSize() { 442c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DEBUGMSG("Master SendGetDataSize (%d)\n", stream_); 443c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott state_ = MASTER_GET_DATA_SIZE; 444c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Message msg; 445c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.command = GET_DATA_SIZE; 446c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.arg1 = stream_; 447c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.long_arg1 = remote_entry_; 448c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SendMsg(msg); 449c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 450c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 451c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MasterSM::DoGetDataSize() { 452c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DEBUGMSG("Master DoGetDataSize: %d\n", input_->msg.arg2); 453c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(state_ == MASTER_GET_DATA_SIZE); 454c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(input_->msg.command == GET_DATA_SIZE); 455c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (input_->msg.result == RESULT_INVALID_PARAMETER) 456c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // No more streams, move to the next entry. 457c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return CloseEntry(); 458c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 459c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (input_->msg.result != RESULT_OK) 460c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return Fail(); 461c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 462c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bytes_remaining_ = input_->msg.arg2; 463c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott offset_ = 0; 464c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SendReadData(); 465c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 466c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 467c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MasterSM::CloseEntry() { 468c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DEBUGMSG("Master CloseEntry\n"); 469c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott printf("%c\r", copied_entries_ % 2 ? 'x' : '+'); 470c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott writer_->CloseEntry(entry_, last_used_, last_modified_); 471c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott entry_ = NULL; 472c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott copied_entries_++; 473c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SendGetPrevEntry(); 474c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 475c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 476c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MasterSM::SendReadData() { 477c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int read_size = std::min(bytes_remaining_, kBufferSize); 478c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DEBUGMSG("Master SendReadData (%d): %d bytes at %d\n", stream_, read_size, 479c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott offset_); 480c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (bytes_remaining_ <= 0) { 481c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stream_++; 482c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (stream_ >= kNumStreams) 483c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return CloseEntry(); 484c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return SendGetDataSize(); 485c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 486c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 487c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott state_ = MASTER_READ_DATA; 488c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Message msg; 489c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.command = READ_DATA; 490c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.arg1 = stream_; 491c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.arg2 = read_size; 492c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.arg3 = offset_; 493c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.long_arg1 = remote_entry_; 494c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SendMsg(msg); 495c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 496c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 497c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MasterSM::DoReadData(int bytes_read) { 498c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DEBUGMSG("Master DoReadData: %d bytes\n", input_->msg.buffer_bytes); 499c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(state_ == MASTER_READ_DATA); 500c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(input_->msg.command == READ_DATA); 501c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (input_->msg.result != RESULT_OK) 502c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return Fail(); 503c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 504c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int read_size = input_->msg.buffer_bytes; 505c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!read_size) { 506c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott printf("Read failed, entry \"%s\" truncated!\n", entry_->GetKey().c_str()); 507c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bytes_remaining_ = 0; 508c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return SendReadData(); 509c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 510c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 511c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_refptr<net::WrappedIOBuffer> buf = 512c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott new net::WrappedIOBuffer(input_->buffer); 513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = writer_->WriteEntry(entry_, stream_, offset_, buf, read_size, 514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &write_callback_); 515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rv == net::ERR_IO_PENDING) { 516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We'll continue in DoReadDataComplete. 517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch read_size_ = read_size; 518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (rv <= 0) 522c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return Fail(); 523c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 524c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott offset_ += read_size; 525c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bytes_remaining_ -= read_size; 526c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Read some more. 527c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SendReadData(); 528c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 529c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid MasterSM::DoReadDataComplete(int ret) { 531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (ret != read_size_) 532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return Fail(); 533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch offset_ += ret; 535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bytes_remaining_ -= ret; 536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Read some more. 537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SendReadData(); 538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 540c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MasterSM::SendQuit() { 541c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DEBUGMSG("Master SendQuit\n"); 542c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott state_ = MASTER_END; 543c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Message msg; 544c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.command = QUIT; 545c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SendMsg(msg); 546c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!IsPending()) 547c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DoEnd(); 548c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 549c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 550c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MasterSM::DoEnd() { 551c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DEBUGMSG("Master DoEnd\n"); 552c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); 553c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 554c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 555c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MasterSM::Fail() { 556c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DEBUGMSG("Master Fail\n"); 557c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott printf("Unexpected failure\n"); 558c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SendQuit(); 559c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 560c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 561c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// ----------------------------------------------------------------------- 562c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 563c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass SlaveSM : public BaseSM { 564c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott public: 565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SlaveSM(const std::wstring& path, HANDLE channel); 566c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual ~SlaveSM(); 567c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 568c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool DoInit(); 569c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void OnIOCompleted(MessageLoopForIO::IOContext* context, 570c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD bytes_transfered, DWORD error); 571c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 572c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott private: 573c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott enum { 574c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SLAVE_INITIAL = 0, 575c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SLAVE_WAITING, 576c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SLAVE_END 577c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott }; 578c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 579c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void DoGetNextEntry(); 580c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void DoGetPrevEntry(); 581c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int32 GetEntryFromList(); 582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void DoGetEntryComplete(int result); 583c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void DoCloseEntry(); 584c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void DoGetKey(); 585c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void DoGetUseTimes(); 586c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void DoGetDataSize(); 587c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void DoReadData(); 588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void DoReadDataComplete(int ret); 589c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void DoEnd(); 590c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Fail(); 591c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 592c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void* iterator_; 593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Message msg_; // Used for DoReadDataComplete and DoGetEntryComplete. 594c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::CompletionCallbackImpl<SlaveSM> read_callback_; 596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch net::CompletionCallbackImpl<SlaveSM> next_callback_; 597c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_ptr<disk_cache::BackendImpl> cache_; 598c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 599c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 600c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSlaveSM::SlaveSM(const std::wstring& path, HANDLE channel) 601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : BaseSM(channel), iterator_(NULL), 602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ALLOW_THIS_IN_INITIALIZER_LIST( 603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch read_callback_(this, &SlaveSM::DoReadDataComplete)), 604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ALLOW_THIS_IN_INITIALIZER_LIST( 605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch next_callback_(this, &SlaveSM::DoGetEntryComplete)) { 606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch disk_cache::Backend* cache; 607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TestCompletionCallback cb; 608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv = disk_cache::CreateCacheBackend(net::DISK_CACHE, 609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath::FromWStringHack(path), 0, 610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch false, 611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cache_thread_.message_loop_proxy(), 6123f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen NULL, &cache, &cb); 613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (cb.GetResult(rv) != net::OK) { 614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch printf("Unable to open cache files\n"); 615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cache_.reset(reinterpret_cast<disk_cache::BackendImpl*>(cache)); 618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cache_->SetUpgradeMode(); 619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 621c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottSlaveSM::~SlaveSM() { 622c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (iterator_) 623c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott cache_->EndEnumeration(&iterator_); 624c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 625c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 626c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid SlaveSM::OnIOCompleted(MessageLoopForIO::IOContext* context, 627c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD bytes_transfered, DWORD error) { 628c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pending_count_--; 629c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (state_ == SLAVE_END) { 630c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (IsPending()) 631c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 632c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return DoEnd(); 633c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 634c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 635c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (context == &out_context_) { 636c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!error) 637c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return; 638c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return Fail(); 639c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 640c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 641c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int bytes_read = static_cast<int>(bytes_transfered); 642c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (bytes_read < sizeof(Message)) { 643c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott printf("Communication breakdown\n"); 644c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return Fail(); 645c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 646c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(state_ == SLAVE_WAITING); 647c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 648c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott switch (input_->msg.command) { 649c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case GET_NEXT_ENTRY: 650c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DoGetNextEntry(); 651c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 652c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case GET_PREV_ENTRY: 653c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DoGetPrevEntry(); 654c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 655c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case CLOSE_ENTRY: 656c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DoCloseEntry(); 657c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 658c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case GET_KEY: 659c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DoGetKey(); 660c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 661c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case GET_USE_TIMES: 662c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DoGetUseTimes(); 663c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 664c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case GET_DATA_SIZE: 665c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DoGetDataSize(); 666c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 667c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case READ_DATA: 668c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DoReadData(); 669c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 670c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott case QUIT: 671c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DoEnd(); 672c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 673c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott default: 674c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott NOTREACHED(); 675c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott break; 676c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 677c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 678c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 679c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottbool SlaveSM::DoInit() { 680c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DEBUGMSG("\t\t\tSlave DoInit\n"); 681c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(state_ == SLAVE_INITIAL); 682c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott state_ = SLAVE_WAITING; 683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!cache_.get()) 684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 686c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return ReceiveMsg(); 687c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 688c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 689c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid SlaveSM::DoGetNextEntry() { 690c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DEBUGMSG("\t\t\tSlave DoGetNextEntry\n"); 691c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Message msg; 692c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.command = GET_NEXT_ENTRY; 693c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 694c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (input_->msg.arg1) { 695c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We only support one list. 696c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.result = RESULT_UNKNOWN_COMMAND; 697c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 698c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.result = GetEntryFromList(); 699c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.long_arg1 = reinterpret_cast<int64>(entry_); 700c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 701c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SendMsg(msg); 702c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 703c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 704c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid SlaveSM::DoGetPrevEntry() { 705c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DEBUGMSG("\t\t\tSlave DoGetPrevEntry\n"); 706c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Message msg; 707c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.command = GET_PREV_ENTRY; 708c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 709c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (input_->msg.arg1) { 710c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We only support one list. 711c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.result = RESULT_UNKNOWN_COMMAND; 712c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 713c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.result = GetEntryFromList(); 714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (msg.result == RESULT_PENDING) { 715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // We are not done yet. 716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch msg_ = msg; 717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 719c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.long_arg1 = reinterpret_cast<int64>(entry_); 720c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 721c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SendMsg(msg); 722c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 723c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 724c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Move to the next or previous entry on the list. 725c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint32 SlaveSM::GetEntryFromList() { 726c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DEBUGMSG("\t\t\tSlave GetEntryFromList\n"); 727c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (input_->msg.long_arg1 != reinterpret_cast<int64>(entry_)) 728c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return RESULT_INVALID_PARAMETER; 729c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 730c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We know that the current iteration is valid. 731c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (entry_) 732c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott entry_->Close(); 733c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 734c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int rv; 735c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (input_->msg.command == GET_NEXT_ENTRY) { 736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = cache_->OpenNextEntry(&iterator_, 737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch reinterpret_cast<disk_cache::Entry**>(&entry_), 738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &next_callback_); 739c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 740c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DCHECK(input_->msg.command == GET_PREV_ENTRY); 741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rv = cache_->OpenPrevEntry(&iterator_, 742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch reinterpret_cast<disk_cache::Entry**>(&entry_), 743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &next_callback_); 744c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(net::ERR_IO_PENDING, rv); 746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return RESULT_PENDING; 747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 748c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SlaveSM::DoGetEntryComplete(int result) { 750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DEBUGMSG("\t\t\tSlave DoGetEntryComplete\n"); 751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (result != net::OK) { 752c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott entry_ = NULL; 753c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DEBUGMSG("\t\t\tSlave end of list\n"); 754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 755c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch msg_.result = RESULT_OK; 757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch msg_.long_arg1 = reinterpret_cast<int64>(entry_); 758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SendMsg(msg_); 759c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 760c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 761c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid SlaveSM::DoCloseEntry() { 762c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DEBUGMSG("\t\t\tSlave DoCloseEntry\n"); 763c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Message msg; 764c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.command = GET_KEY; 765c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 766c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!entry_ || input_->msg.long_arg1 != reinterpret_cast<int64>(entry_)) { 767c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.result = RESULT_INVALID_PARAMETER; 768c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 769c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott entry_->Close(); 770c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott entry_ = NULL; 771c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott cache_->EndEnumeration(&iterator_); 772c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.result = RESULT_OK; 773c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 774c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SendMsg(msg); 775c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 776c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 777c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid SlaveSM::DoGetKey() { 778c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DEBUGMSG("\t\t\tSlave DoGetKey\n"); 779c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Message msg; 780c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.command = GET_KEY; 781c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 782c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!entry_ || input_->msg.long_arg1 != reinterpret_cast<int64>(entry_)) { 783c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.result = RESULT_INVALID_PARAMETER; 784c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 785c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string key = entry_->GetKey(); 786c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.buffer_bytes = std::min(key.size() + 1, 787c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static_cast<size_t>(kBufferSize)); 788c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memcpy(output_->buffer, key.c_str(), msg.buffer_bytes); 789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (msg.buffer_bytes != static_cast<int32>(key.size() + 1)) { 790c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // We don't support moving this entry. Just tell the master. 791c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.result = RESULT_NAME_OVERFLOW; 792c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 793c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.result = RESULT_OK; 794c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 795c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 796c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SendMsg(msg); 797c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 798c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 799c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid SlaveSM::DoGetUseTimes() { 800c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DEBUGMSG("\t\t\tSlave DoGetUseTimes\n"); 801c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Message msg; 802c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.command = GET_USE_TIMES; 803c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 804c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!entry_ || input_->msg.long_arg1 != reinterpret_cast<int64>(entry_)) { 805c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.result = RESULT_INVALID_PARAMETER; 806c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 807c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.long_arg2 = entry_->GetLastUsed().ToInternalValue(); 808c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.long_arg3 = entry_->GetLastModified().ToInternalValue(); 809c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.result = RESULT_OK; 810c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 811c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SendMsg(msg); 812c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 813c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 814c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid SlaveSM::DoGetDataSize() { 815c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DEBUGMSG("\t\t\tSlave DoGetDataSize\n"); 816c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Message msg; 817c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.command = GET_DATA_SIZE; 818c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 819c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int stream = input_->msg.arg1; 820c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!entry_ || input_->msg.long_arg1 != reinterpret_cast<int64>(entry_) || 821c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stream < 0 || stream >= kNumStreams) { 822c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.result = RESULT_INVALID_PARAMETER; 823c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 824c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.arg1 = stream; 825c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.arg2 = entry_->GetDataSize(stream); 826c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.result = RESULT_OK; 827c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 828c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SendMsg(msg); 829c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 830c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 831c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid SlaveSM::DoReadData() { 832c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DEBUGMSG("\t\t\tSlave DoReadData\n"); 833c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Message msg; 834c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.command = READ_DATA; 835c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 836c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int stream = input_->msg.arg1; 837c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int size = input_->msg.arg2; 838c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!entry_ || input_->msg.long_arg1 != reinterpret_cast<int64>(entry_) || 839c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott stream < 0 || stream > 1 || size > kBufferSize) { 840c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.result = RESULT_INVALID_PARAMETER; 841c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 842c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_refptr<net::WrappedIOBuffer> buf = 843c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott new net::WrappedIOBuffer(output_->buffer); 844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int ret = entry_->ReadData(stream, input_->msg.arg3, buf, size, 845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &read_callback_); 846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (ret == net::ERR_IO_PENDING) { 847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Save the message so we can continue were we left. 848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch msg_ = msg; 849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 851c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 852c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.buffer_bytes = (ret < 0) ? 0 : ret; 853c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott msg.result = RESULT_OK; 854c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 855c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SendMsg(msg); 856c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 857c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SlaveSM::DoReadDataComplete(int ret) { 859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DEBUGMSG("\t\t\tSlave DoReadDataComplete\n"); 860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(READ_DATA, msg_.command); 861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch msg_.buffer_bytes = (ret < 0) ? 0 : ret; 862c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch msg_.result = RESULT_OK; 863c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SendMsg(msg_); 864c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 865c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 866c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid SlaveSM::DoEnd() { 867c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DEBUGMSG("\t\t\tSlave DoEnd\n"); 868c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask()); 869c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 870c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 871c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid SlaveSM::Fail() { 872c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DEBUGMSG("\t\t\tSlave Fail\n"); 873c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott printf("Unexpected failure\n"); 874c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott state_ = SLAVE_END; 875c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (IsPending()) { 876c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CancelIo(channel_); 877c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } else { 878c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DoEnd(); 879c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 880c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 881c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 882c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace. 883c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 884c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// ----------------------------------------------------------------------- 885c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 886c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottHANDLE CreateServer(std::wstring* pipe_number) { 887c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::wstring pipe_name(kPipePrefix); 888c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott srand(static_cast<int>(base::Time::Now().ToInternalValue())); 8893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick *pipe_number = base::IntToString16(rand()); 890c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott pipe_name.append(*pipe_number); 891c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 892c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott DWORD mode = PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE | 893c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FILE_FLAG_OVERLAPPED; 894c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 895c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return CreateNamedPipe(pipe_name.c_str(), mode, 0, 1, kChannelSize, 896c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott kChannelSize, 0, NULL); 897c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 898c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 899c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This is the controller process for an upgrade operation. 900c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint CopyCache(const std::wstring& output_path, HANDLE pipe, bool copy_to_text) { 901c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MessageLoop loop(MessageLoop::TYPE_IO); 902c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 903c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MasterSM master(output_path, pipe, copy_to_text); 904c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!master.DoInit()) { 905c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott printf("Unable to talk with the helper\n"); 906c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return -1; 907c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 908c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 909c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott loop.Run(); 910c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return 0; 911c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 912c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 913c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This process will only execute commands from the controller. 914c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint RunSlave(const std::wstring& input_path, const std::wstring& pipe_number) { 915c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MessageLoop loop(MessageLoop::TYPE_IO); 916c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 9173f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen base::win::ScopedHandle pipe(OpenServer(pipe_number)); 918c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!pipe.IsValid()) { 919c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott printf("Unable to open the server pipe\n"); 920c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return -1; 921c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 922c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 923c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SlaveSM slave(input_path, pipe); 924c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott if (!slave.DoInit()) { 925c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott printf("Unable to talk with the main process\n"); 926c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return -1; 927c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 928c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 929c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott loop.Run(); 930c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return 0; 931c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 932