| Index: content/common/fileapi/webblobregistry_impl.cc
 | 
| ===================================================================
 | 
| --- content/common/fileapi/webblobregistry_impl.cc	(revision 183651)
 | 
| +++ content/common/fileapi/webblobregistry_impl.cc	(working copy)
 | 
| @@ -5,9 +5,12 @@
 | 
|  #include "content/common/fileapi/webblobregistry_impl.h"
 | 
|  
 | 
|  #include "base/memory/ref_counted.h"
 | 
| +#include "base/message_loop.h"
 | 
|  #include "base/shared_memory.h"
 | 
|  #include "content/common/child_thread.h"
 | 
|  #include "content/common/fileapi/webblob_messages.h"
 | 
| +#include "content/common/thread_safe_sender.h"
 | 
| +#include "ipc/ipc_sync_message_filter.h"
 | 
|  #include "third_party/WebKit/Source/Platform/chromium/public/WebBlobData.h"
 | 
|  #include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
 | 
|  #include "third_party/WebKit/Source/Platform/chromium/public/WebURL.h"
 | 
| @@ -20,19 +23,125 @@
 | 
|  
 | 
|  namespace content {
 | 
|  
 | 
| -WebBlobRegistryImpl::WebBlobRegistryImpl(ChildThread* child_thread)
 | 
| -    : child_thread_(child_thread) {
 | 
| +WebBlobRegistryImpl::WebBlobRegistryImpl(ThreadSafeSender* sender)
 | 
| +    : sender_(sender) {
 | 
|  }
 | 
|  
 | 
|  WebBlobRegistryImpl::~WebBlobRegistryImpl() {
 | 
|  }
 | 
|  
 | 
| +void WebBlobRegistryImpl::registerBlobData(
 | 
| +    const WebString& uuid, const WebBlobData& data) {
 | 
| +  const size_t kLargeThresholdBytes = 250 * 1024;
 | 
| +  const size_t kMaxSharedMemoryBytes = 10 * 1024 * 1024;
 | 
| +
 | 
| +  const std::string uuid_str(uuid.utf8());
 | 
| +
 | 
| +  sender_->Send(new BlobHostMsg_StartBuildingBlob2(uuid_str));
 | 
| +  size_t i = 0;
 | 
| +  WebBlobData::Item data_item;
 | 
| +  while (data.itemAt(i++, data_item)) {
 | 
| +    webkit_blob::BlobData::Item item;
 | 
| +    switch (data_item.type) {
 | 
| +      case WebBlobData::Item::TypeData: {
 | 
| +        // WebBlobData does not allow partial data items.
 | 
| +        DCHECK(!data_item.offset && data_item.length == -1);
 | 
| +        if (data_item.data.size() == 0)
 | 
| +          break;
 | 
| +        if (data_item.data.size() < kLargeThresholdBytes) {
 | 
| +          item.SetToBytes(data_item.data.data(), data_item.data.size());
 | 
| +          sender_->Send(
 | 
| +              new BlobHostMsg_AppendBlobDataItem2(uuid_str, item));
 | 
| +        } else {
 | 
| +          // We handle larger amounts of data via SharedMemory instead of
 | 
| +          // writing it directly to the IPC channel.
 | 
| +          size_t data_size = data_item.data.size();
 | 
| +          const char* data_ptr = data_item.data.data();
 | 
| +          size_t shared_memory_size = std::min(
 | 
| +              data_size, kMaxSharedMemoryBytes);
 | 
| +          scoped_ptr<base::SharedMemory> shared_memory(
 | 
| +              ChildThread::AllocateSharedMemory(shared_memory_size, sender_));
 | 
| +          CHECK(shared_memory.get());
 | 
| +          while (data_size) {
 | 
| +            size_t chunk_size = std::min(data_size, shared_memory_size);
 | 
| +            memcpy(shared_memory->memory(), data_ptr, chunk_size);
 | 
| +            sender_->Send(new BlobHostMsg_AppendSharedMemory2(
 | 
| +                uuid_str, shared_memory->handle(), chunk_size));
 | 
| +            data_size -= chunk_size;
 | 
| +            data_ptr += chunk_size;
 | 
| +          }
 | 
| +        }
 | 
| +        break;
 | 
| +      }
 | 
| +      case WebBlobData::Item::TypeFile:
 | 
| +        if (data_item.length) {
 | 
| +          item.SetToFilePathRange(
 | 
| +              webkit_base::WebStringToFilePath(data_item.filePath),
 | 
| +              static_cast<uint64>(data_item.offset),
 | 
| +              static_cast<uint64>(data_item.length),
 | 
| +              base::Time::FromDoubleT(data_item.expectedModificationTime));
 | 
| +          sender_->Send(
 | 
| +              new BlobHostMsg_AppendBlobDataItem2(uuid_str, item));
 | 
| +        }
 | 
| +        break;
 | 
| +      case WebBlobData::Item::TypeBlob:
 | 
| +        if (data_item.length) {
 | 
| +          item.SetToBlobRange(
 | 
| +              data_item.blobUUID.utf8(),
 | 
| +              static_cast<uint64>(data_item.offset),
 | 
| +              static_cast<uint64>(data_item.length));
 | 
| +          sender_->Send(
 | 
| +              new BlobHostMsg_AppendBlobDataItem2(uuid_str, item));
 | 
| +        }
 | 
| +        break;
 | 
| +      case WebBlobData::Item::TypeFileSystemURL:
 | 
| +        if (data_item.length) {
 | 
| +          // We only support filesystem URL as of now.
 | 
| +          DCHECK(GURL(data_item.fileSystemURL).SchemeIsFileSystem());
 | 
| +          item.SetToFileSystemUrlRange(
 | 
| +              data_item.fileSystemURL,
 | 
| +              static_cast<uint64>(data_item.offset),
 | 
| +              static_cast<uint64>(data_item.length),
 | 
| +              base::Time::FromDoubleT(data_item.expectedModificationTime));
 | 
| +          sender_->Send(
 | 
| +              new BlobHostMsg_AppendBlobDataItem2(uuid_str, item));
 | 
| +        }
 | 
| +        break;
 | 
| +      default:
 | 
| +        NOTREACHED();
 | 
| +    }
 | 
| +  }
 | 
| +  sender_->Send(new BlobHostMsg_FinishBuildingBlob2(
 | 
| +      uuid_str, data.contentType().utf8()));
 | 
| +}
 | 
| +
 | 
| +void WebBlobRegistryImpl::addBlobDataRef(const WebString& uuid) {
 | 
| +  sender_->Send(new BlobHostMsg_IncrementBlobRefCount(uuid.utf8()));
 | 
| +}
 | 
| +
 | 
| +void WebBlobRegistryImpl::removeBlobDataRef(const WebString& uuid) {
 | 
| +  sender_->Send(new BlobHostMsg_DecrementBlobRefCount(uuid.utf8()));
 | 
| +}
 | 
| +
 | 
| +void WebBlobRegistryImpl::registerPublicBlobURL(
 | 
| +    const WebURL& url, const WebString& uuid) {
 | 
| +  sender_->Send(new BlobHostMsg_RegisterPublicBlobURL(url, uuid.utf8()));
 | 
| +}
 | 
| +
 | 
| +void WebBlobRegistryImpl::revokePublicBlobURL(const WebURL& url) {
 | 
| +  sender_->Send(new BlobHostMsg_RevokePublicBlobURL(url));
 | 
| +}
 | 
| +
 | 
| +
 | 
| +// DEPRECATED
 | 
| +/*
 | 
|  void WebBlobRegistryImpl::registerBlobURL(
 | 
|      const WebURL& url, WebBlobData& data) {
 | 
| +  DCHECK(ChildThread::current()->message_loop() == MessageLoop::current());
 | 
|    const size_t kLargeThresholdBytes = 250 * 1024;
 | 
|    const size_t kMaxSharedMemoryBytes = 10 * 1024 * 1024;
 | 
|  
 | 
| -  child_thread_->Send(new BlobHostMsg_StartBuildingBlob(url));
 | 
| +  sender_->Send(new BlobHostMsg_StartBuildingBlob(url));
 | 
|    size_t i = 0;
 | 
|    WebBlobData::Item data_item;
 | 
|    while (data.itemAt(i++, data_item)) {
 | 
| @@ -45,7 +154,7 @@
 | 
|            break;
 | 
|          if (data_item.data.size() < kLargeThresholdBytes) {
 | 
|            item.SetToBytes(data_item.data.data(), data_item.data.size());
 | 
| -          child_thread_->Send(new BlobHostMsg_AppendBlobDataItem(url, item));
 | 
| +          sender_->Send(new BlobHostMsg_AppendBlobDataItem(url, item));
 | 
|          } else {
 | 
|            // We handle larger amounts of data via SharedMemory instead of
 | 
|            // writing it directly to the IPC channel.
 | 
| @@ -54,12 +163,12 @@
 | 
|            size_t shared_memory_size = std::min(
 | 
|                data_size, kMaxSharedMemoryBytes);
 | 
|            scoped_ptr<base::SharedMemory> shared_memory(
 | 
| -              child_thread_->AllocateSharedMemory(shared_memory_size));
 | 
| +              ChildThread::AllocateSharedMemory(shared_memory_size, sender_));
 | 
|            CHECK(shared_memory.get());
 | 
|            while (data_size) {
 | 
|              size_t chunk_size = std::min(data_size, shared_memory_size);
 | 
|              memcpy(shared_memory->memory(), data_ptr, chunk_size);
 | 
| -            child_thread_->Send(new BlobHostMsg_SyncAppendSharedMemory(
 | 
| +            sender_->Send(new BlobHostMsg_SyncAppendSharedMemory(
 | 
|                  url, shared_memory->handle(), chunk_size));
 | 
|              data_size -= chunk_size;
 | 
|              data_ptr += chunk_size;
 | 
| @@ -74,7 +183,7 @@
 | 
|                static_cast<uint64>(data_item.offset),
 | 
|                static_cast<uint64>(data_item.length),
 | 
|                base::Time::FromDoubleT(data_item.expectedModificationTime));
 | 
| -          child_thread_->Send(new BlobHostMsg_AppendBlobDataItem(url, item));
 | 
| +          sender_->Send(new BlobHostMsg_AppendBlobDataItem(url, item));
 | 
|          }
 | 
|          break;
 | 
|        case WebBlobData::Item::TypeBlob:
 | 
| @@ -83,7 +192,7 @@
 | 
|                data_item.blobURL,
 | 
|                static_cast<uint64>(data_item.offset),
 | 
|                static_cast<uint64>(data_item.length));
 | 
| -          child_thread_->Send(new BlobHostMsg_AppendBlobDataItem(url, item));
 | 
| +          sender_->Send(new BlobHostMsg_AppendBlobDataItem(url, item));
 | 
|          }
 | 
|          break;
 | 
|        case WebBlobData::Item::TypeURL:
 | 
| @@ -95,24 +204,27 @@
 | 
|                static_cast<uint64>(data_item.offset),
 | 
|                static_cast<uint64>(data_item.length),
 | 
|                base::Time::FromDoubleT(data_item.expectedModificationTime));
 | 
| -          child_thread_->Send(new BlobHostMsg_AppendBlobDataItem(url, item));
 | 
| +          sender_->Send(new BlobHostMsg_AppendBlobDataItem(url, item));
 | 
|          }
 | 
|          break;
 | 
|        default:
 | 
|          NOTREACHED();
 | 
|      }
 | 
|    }
 | 
| -  child_thread_->Send(new BlobHostMsg_FinishBuildingBlob(
 | 
| +  sender_->Send(new BlobHostMsg_FinishBuildingBlob(
 | 
|        url, data.contentType().utf8().data()));
 | 
|  }
 | 
|  
 | 
|  void WebBlobRegistryImpl::registerBlobURL(
 | 
|      const WebURL& url, const WebURL& src_url) {
 | 
| -  child_thread_->Send(new BlobHostMsg_CloneBlob(url, src_url));
 | 
| +  DCHECK(ChildThread::current()->message_loop() == MessageLoop::current());
 | 
| +  sender_->Send(new BlobHostMsg_CloneBlob(url, src_url));
 | 
|  }
 | 
|  
 | 
|  void WebBlobRegistryImpl::unregisterBlobURL(const WebURL& url) {
 | 
| -  child_thread_->Send(new BlobHostMsg_RemoveBlob(url));
 | 
| +  DCHECK(ChildThread::current()->message_loop() == MessageLoop::current());
 | 
| +  sender_->Send(new BlobHostMsg_RemoveBlob(url));
 | 
|  }
 | 
| +*/
 | 
|  
 | 
|  }  // namespace content
 | 
| 
 |