Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(44)

Side by Side Diff: mojo/public/cpp/bindings/lib/sync_handle_registry.cc

Issue 2754143005: Use WaitableEvents to wake up sync IPC waiting (Closed)
Patch Set: docs Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 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 "mojo/public/cpp/bindings/sync_handle_registry.h" 5 #include "mojo/public/cpp/bindings/sync_handle_registry.h"
6 6
7 #include "base/lazy_instance.h" 7 #include "base/lazy_instance.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/stl_util.h" 9 #include "base/stl_util.h"
10 #include "base/threading/thread_local.h" 10 #include "base/threading/thread_local.h"
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 void SyncHandleRegistry::UnregisterHandle(const Handle& handle) { 48 void SyncHandleRegistry::UnregisterHandle(const Handle& handle) {
49 DCHECK(thread_checker_.CalledOnValidThread()); 49 DCHECK(thread_checker_.CalledOnValidThread());
50 if (!base::ContainsKey(handles_, handle)) 50 if (!base::ContainsKey(handles_, handle))
51 return; 51 return;
52 52
53 MojoResult result = wait_set_.RemoveHandle(handle); 53 MojoResult result = wait_set_.RemoveHandle(handle);
54 DCHECK_EQ(MOJO_RESULT_OK, result); 54 DCHECK_EQ(MOJO_RESULT_OK, result);
55 handles_.erase(handle); 55 handles_.erase(handle);
56 } 56 }
57 57
58 bool SyncHandleRegistry::RegisterEvent(base::WaitableEvent* event,
59 const base::Closure& callback) {
60 auto result = events_.insert({event, callback});
61 DCHECK(result.second);
62 MojoResult rv = wait_set_.AddEvent(event);
63 if (rv == MOJO_RESULT_OK)
64 return true;
65 DCHECK_EQ(MOJO_RESULT_ALREADY_EXISTS, rv);
66 return false;
67 }
68
69 void SyncHandleRegistry::UnregisterEvent(base::WaitableEvent* event) {
70 auto it = events_.find(event);
71 DCHECK(it != events_.end());
72 events_.erase(it);
73 MojoResult rv = wait_set_.RemoveEvent(event);
74 DCHECK_EQ(MOJO_RESULT_OK, rv);
75 }
76
58 bool SyncHandleRegistry::WatchAllHandles(const bool* should_stop[], 77 bool SyncHandleRegistry::WatchAllHandles(const bool* should_stop[],
59 size_t count) { 78 size_t count) {
60 DCHECK(thread_checker_.CalledOnValidThread()); 79 DCHECK(thread_checker_.CalledOnValidThread());
61 80
62 size_t num_ready_handles; 81 size_t num_ready_handles;
63 Handle ready_handle; 82 Handle ready_handle;
64 MojoResult ready_handle_result; 83 MojoResult ready_handle_result;
65 84
66 scoped_refptr<SyncHandleRegistry> preserver(this); 85 scoped_refptr<SyncHandleRegistry> preserver(this);
67 while (true) { 86 while (true) {
68 for (size_t i = 0; i < count; ++i) 87 for (size_t i = 0; i < count; ++i)
69 if (*should_stop[i]) 88 if (*should_stop[i])
70 return true; 89 return true;
71 90
72 // TODO(yzshen): Theoretically it can reduce sync call re-entrancy if we 91 // TODO(yzshen): Theoretically it can reduce sync call re-entrancy if we
73 // give priority to the handle that is waiting for sync response. 92 // give priority to the handle that is waiting for sync response.
93 base::WaitableEvent* ready_event = nullptr;
74 num_ready_handles = 1; 94 num_ready_handles = 1;
75 wait_set_.Wait(&num_ready_handles, &ready_handle, &ready_handle_result); 95 wait_set_.Wait(&ready_event, &num_ready_handles, &ready_handle,
76 DCHECK_EQ(1u, num_ready_handles); 96 &ready_handle_result);
97 if (num_ready_handles) {
98 DCHECK_EQ(1u, num_ready_handles);
99 const auto iter = handles_.find(ready_handle);
100 iter->second.Run(ready_handle_result);
101 }
77 102
78 const auto iter = handles_.find(ready_handle); 103 if (ready_event) {
79 iter->second.Run(ready_handle_result); 104 const auto iter = events_.find(ready_event);
105 DCHECK(iter != events_.end());
106 iter->second.Run();
107 }
80 }; 108 };
81 109
82 return false; 110 return false;
83 } 111 }
84 112
85 SyncHandleRegistry::SyncHandleRegistry() { 113 SyncHandleRegistry::SyncHandleRegistry() {
86 DCHECK(!g_current_sync_handle_watcher.Pointer()->Get()); 114 DCHECK(!g_current_sync_handle_watcher.Pointer()->Get());
87 g_current_sync_handle_watcher.Pointer()->Set(this); 115 g_current_sync_handle_watcher.Pointer()->Set(this);
88 } 116 }
89 117
90 SyncHandleRegistry::~SyncHandleRegistry() { 118 SyncHandleRegistry::~SyncHandleRegistry() {
91 DCHECK(thread_checker_.CalledOnValidThread()); 119 DCHECK(thread_checker_.CalledOnValidThread());
92 120
93 // This object may be destructed after the thread local storage slot used by 121 // This object may be destructed after the thread local storage slot used by
94 // |g_current_sync_handle_watcher| is reset during thread shutdown. 122 // |g_current_sync_handle_watcher| is reset during thread shutdown.
95 // For example, another slot in the thread local storage holds a referrence to 123 // For example, another slot in the thread local storage holds a referrence to
96 // this object, and that slot is cleaned up after 124 // this object, and that slot is cleaned up after
97 // |g_current_sync_handle_watcher|. 125 // |g_current_sync_handle_watcher|.
98 if (!g_current_sync_handle_watcher.Pointer()->Get()) 126 if (!g_current_sync_handle_watcher.Pointer()->Get())
99 return; 127 return;
100 128
101 // If this breaks, it is likely that the global variable is bulit into and 129 // If this breaks, it is likely that the global variable is bulit into and
102 // accessed from multiple modules. 130 // accessed from multiple modules.
103 DCHECK_EQ(this, g_current_sync_handle_watcher.Pointer()->Get()); 131 DCHECK_EQ(this, g_current_sync_handle_watcher.Pointer()->Get());
104 132
105 g_current_sync_handle_watcher.Pointer()->Set(nullptr); 133 g_current_sync_handle_watcher.Pointer()->Set(nullptr);
106 } 134 }
107 135
108 } // namespace mojo 136 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698