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

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: . 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::WatchAllHandles(const bool* should_stop[], 58 bool SyncHandleRegistry::RegisterEvent(base::WaitableEvent* event,
59 size_t count) { 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
77 bool SyncHandleRegistry::Wait(const bool* should_stop[], size_t count) {
60 DCHECK(thread_checker_.CalledOnValidThread()); 78 DCHECK(thread_checker_.CalledOnValidThread());
61 79
62 size_t num_ready_handles; 80 size_t num_ready_handles;
63 Handle ready_handle; 81 Handle ready_handle;
64 MojoResult ready_handle_result; 82 MojoResult ready_handle_result;
65 83
66 scoped_refptr<SyncHandleRegistry> preserver(this); 84 scoped_refptr<SyncHandleRegistry> preserver(this);
67 while (true) { 85 while (true) {
68 for (size_t i = 0; i < count; ++i) 86 for (size_t i = 0; i < count; ++i)
69 if (*should_stop[i]) 87 if (*should_stop[i])
70 return true; 88 return true;
71 89
72 // TODO(yzshen): Theoretically it can reduce sync call re-entrancy if we 90 // TODO(yzshen): Theoretically it can reduce sync call re-entrancy if we
73 // give priority to the handle that is waiting for sync response. 91 // give priority to the handle that is waiting for sync response.
92 base::WaitableEvent* ready_event = nullptr;
74 num_ready_handles = 1; 93 num_ready_handles = 1;
75 wait_set_.Wait(&num_ready_handles, &ready_handle, &ready_handle_result); 94 wait_set_.Wait(&ready_event, &num_ready_handles, &ready_handle,
76 DCHECK_EQ(1u, num_ready_handles); 95 &ready_handle_result);
96 if (num_ready_handles) {
97 DCHECK_EQ(1u, num_ready_handles);
98 const auto iter = handles_.find(ready_handle);
99 iter->second.Run(ready_handle_result);
100 }
77 101
78 const auto iter = handles_.find(ready_handle); 102 if (ready_event) {
79 iter->second.Run(ready_handle_result); 103 const auto iter = events_.find(ready_event);
104 DCHECK(iter != events_.end());
105 iter->second.Run();
106 }
80 }; 107 };
81 108
82 return false; 109 return false;
83 } 110 }
84 111
85 SyncHandleRegistry::SyncHandleRegistry() { 112 SyncHandleRegistry::SyncHandleRegistry() {
86 DCHECK(!g_current_sync_handle_watcher.Pointer()->Get()); 113 DCHECK(!g_current_sync_handle_watcher.Pointer()->Get());
87 g_current_sync_handle_watcher.Pointer()->Set(this); 114 g_current_sync_handle_watcher.Pointer()->Set(this);
88 } 115 }
89 116
90 SyncHandleRegistry::~SyncHandleRegistry() { 117 SyncHandleRegistry::~SyncHandleRegistry() {
91 DCHECK(thread_checker_.CalledOnValidThread()); 118 DCHECK(thread_checker_.CalledOnValidThread());
92 119
93 // This object may be destructed after the thread local storage slot used by 120 // This object may be destructed after the thread local storage slot used by
94 // |g_current_sync_handle_watcher| is reset during thread shutdown. 121 // |g_current_sync_handle_watcher| is reset during thread shutdown.
95 // For example, another slot in the thread local storage holds a referrence to 122 // For example, another slot in the thread local storage holds a referrence to
96 // this object, and that slot is cleaned up after 123 // this object, and that slot is cleaned up after
97 // |g_current_sync_handle_watcher|. 124 // |g_current_sync_handle_watcher|.
98 if (!g_current_sync_handle_watcher.Pointer()->Get()) 125 if (!g_current_sync_handle_watcher.Pointer()->Get())
99 return; 126 return;
100 127
101 // If this breaks, it is likely that the global variable is bulit into and 128 // If this breaks, it is likely that the global variable is bulit into and
102 // accessed from multiple modules. 129 // accessed from multiple modules.
103 DCHECK_EQ(this, g_current_sync_handle_watcher.Pointer()->Get()); 130 DCHECK_EQ(this, g_current_sync_handle_watcher.Pointer()->Get());
104 131
105 g_current_sync_handle_watcher.Pointer()->Set(nullptr); 132 g_current_sync_handle_watcher.Pointer()->Set(nullptr);
106 } 133 }
107 134
108 } // namespace mojo 135 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/public/cpp/bindings/lib/sync_event_watcher.cc ('k') | mojo/public/cpp/bindings/lib/sync_handle_watcher.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698