| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/webcrypto/webcrypto_impl.h" | 5 #include "components/webcrypto/webcrypto_impl.h" |
| 6 | 6 |
| 7 #include <limits.h> | 7 #include <limits.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <memory> | 10 #include <memory> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/lazy_instance.h" | 13 #include "base/lazy_instance.h" |
| 14 #include "base/location.h" | 14 #include "base/location.h" |
| 15 #include "base/logging.h" | 15 #include "base/logging.h" |
| 16 #include "base/macros.h" |
| 16 #include "base/single_thread_task_runner.h" | 17 #include "base/single_thread_task_runner.h" |
| 17 #include "base/task_runner.h" | 18 #include "base/task_runner.h" |
| 18 #include "base/threading/sequenced_worker_pool.h" | 19 #include "base/threading/thread.h" |
| 19 #include "base/threading/thread_task_runner_handle.h" | 20 #include "base/threading/thread_task_runner_handle.h" |
| 20 #include "base/threading/worker_pool.h" | |
| 21 #include "components/webcrypto/algorithm_dispatch.h" | 21 #include "components/webcrypto/algorithm_dispatch.h" |
| 22 #include "components/webcrypto/crypto_data.h" | 22 #include "components/webcrypto/crypto_data.h" |
| 23 #include "components/webcrypto/generate_key_result.h" | 23 #include "components/webcrypto/generate_key_result.h" |
| 24 #include "components/webcrypto/status.h" | 24 #include "components/webcrypto/status.h" |
| 25 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" | 25 #include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h" |
| 26 #include "third_party/WebKit/public/platform/WebString.h" | 26 #include "third_party/WebKit/public/platform/WebString.h" |
| 27 | 27 |
| 28 namespace webcrypto { | 28 namespace webcrypto { |
| 29 | 29 |
| 30 using webcrypto::Status; | 30 using webcrypto::Status; |
| 31 | 31 |
| 32 namespace { | 32 namespace { |
| 33 | 33 |
| 34 // --------------------- | 34 // --------------------- |
| 35 // Threading | 35 // Threading |
| 36 // --------------------- | 36 // --------------------- |
| 37 // | 37 // |
| 38 // WebCrypto operations can be slow. For instance generating an RSA key can | 38 // WebCrypto operations can be slow. For instance generating an RSA key can |
| 39 // take seconds. | 39 // take seconds. |
| 40 // | 40 // |
| 41 // The strategy used here is to run a sequenced worker pool for all WebCrypto | 41 // The strategy used here is to run a worker pool for all WebCrypto operations |
| 42 // operations (except structured cloning). This same pool is also used by | 42 // (except structured cloning). This same pool is also used by requests started |
| 43 // requests started from Blink Web Workers. | 43 // from Blink Web Workers. |
| 44 // | 44 // |
| 45 // A few notes to keep in mind: | 45 // A few notes to keep in mind: |
| 46 // | 46 // |
| 47 // * PostTaskAndReply() is not used because of how it handles failures -- it | 47 // * PostTaskAndReply() is not used because of how it handles failures -- it |
| 48 // leaks the callback when failing to post back to the origin thread. | 48 // leaks the callback when failing to post back to the origin thread. |
| 49 // | 49 // |
| 50 // This is a problem since WebCrypto may be called from WebWorker threads, | 50 // This is a problem since WebCrypto may be called from WebWorker threads, |
| 51 // which may be aborted at any time. Leaking would be undesirable, and | 51 // which may be aborted at any time. Leaking would be undesirable, and |
| 52 // reachable in practice. | 52 // reachable in practice. |
| 53 // | 53 // |
| (...skipping 10 matching lines...) Expand all Loading... |
| 64 // following ImportKey()). | 64 // following ImportKey()). |
| 65 // | 65 // |
| 66 // * blink::WebCryptoResult is not threadsafe and should only be operated on | 66 // * blink::WebCryptoResult is not threadsafe and should only be operated on |
| 67 // the target Blink thread. HOWEVER, it is safe to delete it from any thread. | 67 // the target Blink thread. HOWEVER, it is safe to delete it from any thread. |
| 68 // This can happen if by the time the operation has completed in the crypto | 68 // This can happen if by the time the operation has completed in the crypto |
| 69 // worker pool, the Blink worker thread that initiated the request is gone. | 69 // worker pool, the Blink worker thread that initiated the request is gone. |
| 70 // Posting back to the origin thread will fail, and the WebCryptoResult will | 70 // Posting back to the origin thread will fail, and the WebCryptoResult will |
| 71 // be deleted while running in the crypto worker pool. | 71 // be deleted while running in the crypto worker pool. |
| 72 class CryptoThreadPool { | 72 class CryptoThreadPool { |
| 73 public: | 73 public: |
| 74 CryptoThreadPool() | 74 CryptoThreadPool() : worker_thread_("WebCrypto") { |
| 75 : worker_pool_( | 75 base::Thread::Options options; |
| 76 new base::SequencedWorkerPool(1, | 76 options.joinable = false; |
| 77 "WebCrypto", | 77 worker_thread_.StartWithOptions(options); |
| 78 base::TaskPriority::USER_BLOCKING)), | 78 } |
| 79 task_runner_(worker_pool_->GetSequencedTaskRunnerWithShutdownBehavior( | |
| 80 worker_pool_->GetSequenceToken(), | |
| 81 base::SequencedWorkerPool::CONTINUE_ON_SHUTDOWN)) {} | |
| 82 | 79 |
| 83 static bool PostTask(const tracked_objects::Location& from_here, | 80 static bool PostTask(const tracked_objects::Location& from_here, |
| 84 const base::Closure& task); | 81 const base::Closure& task); |
| 85 | 82 |
| 86 private: | 83 private: |
| 87 scoped_refptr<base::SequencedWorkerPool> worker_pool_; | 84 // TODO(gab): the pool is currently using a single non-joinable thread to |
| 88 scoped_refptr<base::SequencedTaskRunner> task_runner_; | 85 // mimic the old behavior of using a CONTINUE_ON_SHUTDOWN SequencedTaskRunner |
| 86 // on a single-threaded SequencedWorkerPool, but we'd like to consider using |
| 87 // the TaskScheduler here and allowing multiple threads (SEQUENCED or even |
| 88 // PARALLEL ExecutionMode: http://crbug.com/623700). |
| 89 base::Thread worker_thread_; |
| 90 |
| 91 DISALLOW_COPY_AND_ASSIGN(CryptoThreadPool); |
| 89 }; | 92 }; |
| 90 | 93 |
| 91 base::LazyInstance<CryptoThreadPool>::Leaky crypto_thread_pool = | 94 base::LazyInstance<CryptoThreadPool>::Leaky crypto_thread_pool = |
| 92 LAZY_INSTANCE_INITIALIZER; | 95 LAZY_INSTANCE_INITIALIZER; |
| 93 | 96 |
| 94 bool CryptoThreadPool::PostTask(const tracked_objects::Location& from_here, | 97 bool CryptoThreadPool::PostTask(const tracked_objects::Location& from_here, |
| 95 const base::Closure& task) { | 98 const base::Closure& task) { |
| 96 return crypto_thread_pool.Get().task_runner_->PostTask(from_here, task); | 99 return crypto_thread_pool.Get().worker_thread_.task_runner()->PostTask( |
| 100 from_here, task); |
| 97 } | 101 } |
| 98 | 102 |
| 99 void CompleteWithThreadPoolError(blink::WebCryptoResult* result) { | 103 void CompleteWithThreadPoolError(blink::WebCryptoResult* result) { |
| 100 result->completeWithError(blink::WebCryptoErrorTypeOperation, | 104 result->completeWithError(blink::WebCryptoErrorTypeOperation, |
| 101 "Failed posting to crypto worker pool"); | 105 "Failed posting to crypto worker pool"); |
| 102 } | 106 } |
| 103 | 107 |
| 104 void CompleteWithError(const Status& status, blink::WebCryptoResult* result) { | 108 void CompleteWithError(const Status& status, blink::WebCryptoResult* result) { |
| 105 DCHECK(status.IsError()); | 109 DCHECK(status.IsError()); |
| 106 | 110 |
| (...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 771 webcrypto::CryptoData(key_data, key_data_size), &key); | 775 webcrypto::CryptoData(key_data, key_data_size), &key); |
| 772 } | 776 } |
| 773 | 777 |
| 774 bool WebCryptoImpl::serializeKeyForClone( | 778 bool WebCryptoImpl::serializeKeyForClone( |
| 775 const blink::WebCryptoKey& key, | 779 const blink::WebCryptoKey& key, |
| 776 blink::WebVector<unsigned char>& key_data) { | 780 blink::WebVector<unsigned char>& key_data) { |
| 777 return webcrypto::SerializeKeyForClone(key, &key_data); | 781 return webcrypto::SerializeKeyForClone(key, &key_data); |
| 778 } | 782 } |
| 779 | 783 |
| 780 } // namespace webcrypto | 784 } // namespace webcrypto |
| OLD | NEW |