Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Threading | 1 # Threading |
| 2 | 2 |
| 3 [TOC] | 3 [TOC] |
| 4 | 4 |
| 5 ## Overview | 5 ## Overview |
| 6 | 6 |
| 7 Chromium is a very multithreaded product. We try to keep the UI as responsive as | 7 Chromium is a very multithreaded product. We try to keep the UI as responsive as |
| 8 possible, and this means not blocking the UI thread with any blocking I/O or | 8 possible, and this means not blocking the UI thread with any blocking I/O or |
| 9 other expensive operations. Our approach is to use message passing as the way of | 9 other expensive operations. Our approach is to use message passing as the way of |
| 10 communicating between threads. We discourage locking and threadsafe | 10 communicating between threads. We discourage locking and threadsafe |
| 11 objects. Instead, objects live on only one thread, we pass messages between | 11 objects. Instead, objects live on only one thread, we pass messages between |
| 12 threads for communication, and we use callback interfaces (implemented by | 12 threads for communication, and we use callback interfaces (implemented by |
| 13 message passing) for most cross-thread requests. | 13 message passing) for most cross-thread requests. |
| 14 | 14 |
| 15 The `Thread` object is defined in | 15 The `Thread` object is defined in |
| 16 [`base/threading/thread.h`](https://cs.chromium.org/chromium/src/base/threading/ thread.h). | 16 [`base/threading/thread.h`](https://cs.chromium.org/chromium/src/base/threading/ thread.h). |
| 17 In general you should probably use one of the existing threads described below | 17 In general you should probably use one of the existing threads described below |
| 18 rather than make new ones. We already have a lot of threads that are difficult | 18 rather than make new ones. We already have a lot of threads that are difficult |
| 19 to keep track of. Each thread has a `MessageLoop` (see | 19 to keep track of. Each thread has a `MessageLoop` (see |
| 20 [`base/message_loop/message_loop.h`](https://cs.chromium.org/chromium/src/base/m essage_loop/message_loop.h) | 20 [`base/message_loop/message_loop.h`](https://cs.chromium.org/chromium/src/base/m essage_loop/message_loop.h) |
| 21 that processes messages for that thread. You can get the message loop for a | 21 that processes messages for that thread. You can get the message loop for a |
| 22 thread using the `Thread.message_loop()` function. More details about | 22 thread using the `Thread.message_loop()` function. More details about |
| 23 `MessageLoop` can be found in | 23 `MessageLoop` can be found in |
| 24 [Anatomy of Chromium MessageLoop](https://docs.google.com/document/d/1_pJUHO3f3V yRSQjEhKVvUU7NzCyuTCQshZvbWeQiCXU/view#). | 24 [Anatomy of Chromium MessageLoop](https://docs.google.com/document/d/1_pJUHO3f3V yRSQjEhKVvUU7NzCyuTCQshZvbWeQiCXU/view#). |
| 25 | 25 |
| 26 ## Existing threads | 26 ## Existing threads |
| 27 | 27 |
| 28 Most threads are managed by the BrowserProcess object, which acts as the service | 28 Most threads are managed by the BrowserProcess object, which acts as the service |
| 29 manager for the main "browser" process. By default, everything happens on the UI | 29 manager for the main "browser" process. By default, everything happens on the UI |
| 30 thread. We have pushed certain classes of processing into these other | 30 thread. We have pushed certain classes of processing into these other |
| 31 threads. It has getters for the following threads: | 31 threads. It has getters for the following threads: |
| 32 | 32 |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 235 raw pointer with `make_scoped_refptr()`: | 235 raw pointer with `make_scoped_refptr()`: |
| 236 | 236 |
| 237 class SomeParamObject : public base::RefCountedThreadSafe<SomeParamObject> { | 237 class SomeParamObject : public base::RefCountedThreadSafe<SomeParamObject> { |
| 238 ... | 238 ... |
| 239 }; | 239 }; |
| 240 | 240 |
| 241 class MyObject : public base::RefCountedThreadSafe<MyObject> { | 241 class MyObject : public base::RefCountedThreadSafe<MyObject> { |
| 242 public: | 242 public: |
| 243 void DoSomething() { | 243 void DoSomething() { |
| 244 scoped_refptr<SomeParamObject> param(new SomeParamObject); | 244 scoped_refptr<SomeParamObject> param(new SomeParamObject); |
| 245 thread_->message_loop()->PostTask(FROM_HERE | 245 |
| 246 base::Bind(&MyObject::DoSomethingOnAnotherThread, this, param)); | 246 // Moving |param| prevents an extra AddRef()/Release() pair. |
|
lazyboy
2017/06/23 20:43:27
Nice, I think you should separate out this std::mo
karandeepb
2017/06/23 22:48:46
Done. Yeah it doesn't compile.
| |
| 247 thread_->message_loop()->PostTask(FROM_HERE, | |
| 248 base::Bind(&MyObject::DoSomethingOnAnotherThread, this, | |
| 249 base::RetainedRef(std::move(param)))); | |
| 247 } | 250 } |
| 248 void DoSomething2() { | 251 void DoSomething2() { |
| 249 SomeParamObject* param = new SomeParamObject; | 252 SomeParamObject* param = new SomeParamObject; |
| 250 thread_->message_loop()->PostTask(FROM_HERE | 253 thread_->message_loop()->PostTask(FROM_HERE, |
| 251 base::Bind(&MyObject::DoSomethingOnAnotherThread, this, | 254 base::Bind(&MyObject::DoSomethingOnAnotherThread, this, |
| 252 make_scoped_refptr(param))); | 255 base::RetainedRef(make_scoped_refptr(param)))); |
| 253 } | 256 } |
| 254 // Note how this takes a raw pointer. The important part is that | 257 |
| 255 // base::Bind() was passed a scoped_refptr; using a scoped_refptr | 258 // Note how this takes a raw pointer. The important part is that using |
|
lazyboy
2017/06/23 20:43:27
The comment here before was emphasizing that inste
karandeepb
2017/06/23 22:48:46
Done.
| |
| 256 // here would result in an extra AddRef()/Release() pair. | 259 // base::RetainedRef allows passing a raw pointer when the callback is run |
| 260 // preventing an extra AddRef()/Release() pair. | |
| 257 void DoSomethingOnAnotherThread(SomeParamObject* param) { | 261 void DoSomethingOnAnotherThread(SomeParamObject* param) { |
| 258 ... | 262 ... |
| 259 } | 263 } |
| 260 }; | 264 }; |
| 261 | 265 |
| 262 If you want to pass the object without taking a reference on it, wrap the | 266 If you want to pass the object without taking a reference on it, wrap the |
| 263 argument with `base::Unretained()`. Again, using this means there are external | 267 argument with `base::Unretained()`. Again, using this means there are external |
| 264 guarantees on the lifetime of the object, so tread carefully! | 268 guarantees on the lifetime of the object, so tread carefully! |
| 265 | 269 |
| 266 If your object has a non-trivial destructor that needs to run on a specific | 270 If your object has a non-trivial destructor that needs to run on a specific |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 487 int some_input1, int some_input2) { | 491 int some_input1, int some_input2) { |
| 488 if (request->canceled()) | 492 if (request->canceled()) |
| 489 return; | 493 return; |
| 490 | 494 |
| 491 ... do your processing ... | 495 ... do your processing ... |
| 492 | 496 |
| 493 // Execute ForwardResult() like you would do Run() on the base::Callback <>. | 497 // Execute ForwardResult() like you would do Run() on the base::Callback <>. |
| 494 request->ForwardResult(return_value); | 498 request->ForwardResult(return_value); |
| 495 } | 499 } |
| 496 }; | 500 }; |
| OLD | NEW |