OLD | NEW |
| (Empty) |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "services/service_manager/public/cpp/service_context_ref.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/memory/ptr_util.h" | |
9 #include "base/message_loop/message_loop.h" | |
10 #include "base/threading/thread_checker.h" | |
11 #include "base/threading/thread_task_runner_handle.h" | |
12 | |
13 namespace service_manager { | |
14 | |
15 class ServiceContextRefImpl : public ServiceContextRef { | |
16 public: | |
17 ServiceContextRefImpl( | |
18 base::WeakPtr<ServiceContextRefFactory> factory, | |
19 scoped_refptr<base::SingleThreadTaskRunner> service_task_runner) | |
20 : factory_(factory), | |
21 service_task_runner_(service_task_runner) { | |
22 // This object is not thread-safe but may be used exclusively on a different | |
23 // thread from the one which constructed it. | |
24 thread_checker_.DetachFromThread(); | |
25 } | |
26 | |
27 ~ServiceContextRefImpl() override { | |
28 DCHECK(thread_checker_.CalledOnValidThread()); | |
29 | |
30 if (service_task_runner_->BelongsToCurrentThread() && factory_) { | |
31 factory_->Release(); | |
32 } else { | |
33 service_task_runner_->PostTask( | |
34 FROM_HERE, | |
35 base::Bind(&ServiceContextRefFactory::Release, factory_)); | |
36 } | |
37 } | |
38 | |
39 private: | |
40 // ServiceContextRef: | |
41 std::unique_ptr<ServiceContextRef> Clone() override { | |
42 DCHECK(thread_checker_.CalledOnValidThread()); | |
43 | |
44 if (service_task_runner_->BelongsToCurrentThread() && factory_) { | |
45 factory_->AddRef(); | |
46 } else { | |
47 service_task_runner_->PostTask( | |
48 FROM_HERE, | |
49 base::Bind(&ServiceContextRefFactory::AddRef, factory_)); | |
50 } | |
51 | |
52 return base::MakeUnique<ServiceContextRefImpl>(factory_, | |
53 service_task_runner_); | |
54 } | |
55 | |
56 base::WeakPtr<ServiceContextRefFactory> factory_; | |
57 scoped_refptr<base::SingleThreadTaskRunner> service_task_runner_; | |
58 base::ThreadChecker thread_checker_; | |
59 | |
60 DISALLOW_COPY_AND_ASSIGN(ServiceContextRefImpl); | |
61 }; | |
62 | |
63 ServiceContextRefFactory::ServiceContextRefFactory( | |
64 const base::Closure& quit_closure) | |
65 : quit_closure_(quit_closure), weak_factory_(this) { | |
66 DCHECK(!quit_closure_.is_null()); | |
67 } | |
68 | |
69 ServiceContextRefFactory::~ServiceContextRefFactory() {} | |
70 | |
71 std::unique_ptr<ServiceContextRef> ServiceContextRefFactory::CreateRef() { | |
72 AddRef(); | |
73 return base::MakeUnique<ServiceContextRefImpl>( | |
74 weak_factory_.GetWeakPtr(), base::ThreadTaskRunnerHandle::Get()); | |
75 } | |
76 | |
77 void ServiceContextRefFactory::AddRef() { | |
78 ++ref_count_; | |
79 } | |
80 | |
81 void ServiceContextRefFactory::Release() { | |
82 if (!--ref_count_) | |
83 quit_closure_.Run(); | |
84 } | |
85 | |
86 } // namespace service_manager | |
OLD | NEW |