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 |