| Index: chrome/browser/image_decoder.cc
 | 
| diff --git a/chrome/browser/image_decoder.cc b/chrome/browser/image_decoder.cc
 | 
| index 6d7b948aa7f63a79dc817fc41088aec47cd588d3..682789f9c6af128183a5d1c9b6b7bc16f84268ca 100644
 | 
| --- a/chrome/browser/image_decoder.cc
 | 
| +++ b/chrome/browser/image_decoder.cc
 | 
| @@ -5,6 +5,7 @@
 | 
|  #include "chrome/browser/image_decoder.h"
 | 
|  
 | 
|  #include "base/bind.h"
 | 
| +#include "base/threading/sequenced_worker_pool.h"
 | 
|  #include "chrome/browser/browser_process.h"
 | 
|  #include "chrome/common/chrome_utility_messages.h"
 | 
|  #include "content/public/browser/browser_thread.h"
 | 
| @@ -34,6 +35,17 @@ void ImageDecoder::Start() {
 | 
|       base::Bind(&ImageDecoder::DecodeImageInSandbox, this, image_data_));
 | 
|  }
 | 
|  
 | 
| +void ImageDecoder::Start(std::string sequence_token_name) {
 | 
| +  if (sequence_token_name.empty()) {
 | 
| +    NOTREACHED();
 | 
| +    return;
 | 
| +  }
 | 
| +  sequence_token_name_ = sequence_token_name;
 | 
| +  BrowserThread::PostTask(
 | 
| +     BrowserThread::IO, FROM_HERE,
 | 
| +     base::Bind(&ImageDecoder::DecodeImageInSandbox, this, image_data_));
 | 
| +}
 | 
| +
 | 
|  bool ImageDecoder::OnMessageReceived(const IPC::Message& message) {
 | 
|    bool handled = true;
 | 
|    IPC_BEGIN_MESSAGE_MAP(ImageDecoder, message)
 | 
| @@ -46,14 +58,25 @@ bool ImageDecoder::OnMessageReceived(const IPC::Message& message) {
 | 
|    return handled;
 | 
|  }
 | 
|  
 | 
| +bool ImageDecoder::CalledOnValidThreadOrWorkerThread() {
 | 
| +  if (sequence_token_name_.empty()) {
 | 
| +    return BrowserThread::CurrentlyOn(target_thread_id_);
 | 
| +  } else {
 | 
| +    base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool();
 | 
| +    base::SequencedWorkerPool::SequenceToken sequence_token = pool->
 | 
| +        GetNamedSequenceToken(sequence_token_name_);
 | 
| +    return pool->IsRunningSequenceOnCurrentThread(sequence_token);
 | 
| +  }
 | 
| +}
 | 
| +
 | 
|  void ImageDecoder::OnDecodeImageSucceeded(const SkBitmap& decoded_image) {
 | 
| -  DCHECK(BrowserThread::CurrentlyOn(target_thread_id_));
 | 
| +  DCHECK(CalledOnValidThreadOrWorkerThread());
 | 
|    if (delegate_)
 | 
|      delegate_->OnImageDecoded(this, decoded_image);
 | 
|  }
 | 
|  
 | 
|  void ImageDecoder::OnDecodeImageFailed() {
 | 
| -  DCHECK(BrowserThread::CurrentlyOn(target_thread_id_));
 | 
| +  DCHECK(CalledOnValidThreadOrWorkerThread());
 | 
|    if (delegate_)
 | 
|      delegate_->OnDecodeImageFailed(this);
 | 
|  }
 | 
| @@ -61,8 +84,17 @@ void ImageDecoder::OnDecodeImageFailed() {
 | 
|  void ImageDecoder::DecodeImageInSandbox(
 | 
|      const std::vector<unsigned char>& image_data) {
 | 
|    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
 | 
| -  UtilityProcessHost* utility_process_host = UtilityProcessHost::Create(
 | 
| -      this, BrowserThread::GetMessageLoopProxyForThread(target_thread_id_));
 | 
| +  UtilityProcessHost* utility_process_host;
 | 
| +  if (sequence_token_name_.empty()) {
 | 
| +    utility_process_host = UtilityProcessHost::Create(
 | 
| +        this, BrowserThread::GetMessageLoopProxyForThread(target_thread_id_));
 | 
| +  } else {
 | 
| +    base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool();
 | 
| +    base::SequencedWorkerPool::SequenceToken sequence_token = pool->
 | 
| +        GetNamedSequenceToken(sequence_token_name_);
 | 
| +    utility_process_host = UtilityProcessHost::Create(
 | 
| +        this, pool->GetSequencedTaskRunner(sequence_token).get());
 | 
| +  }
 | 
|    utility_process_host->EnableZygote();
 | 
|    if (image_codec_ == ROBUST_JPEG_CODEC) {
 | 
|      utility_process_host->Send(
 | 
| 
 |