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

Unified Diff: ppapi/nacl_irt/manifest_service.cc

Issue 334593004: Fix race condition on ManifestService initialization. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ppapi/nacl_irt/manifest_service.cc
diff --git a/ppapi/nacl_irt/manifest_service.cc b/ppapi/nacl_irt/manifest_service.cc
index 85b7fae2c960c9ca5ca156abf3213b9deed1524a..441c401e92381ff529b53325452992a50709fef4 100644
--- a/ppapi/nacl_irt/manifest_service.cc
+++ b/ppapi/nacl_irt/manifest_service.cc
@@ -17,11 +17,54 @@ namespace ppapi {
const char kFilePrefix[] = "files/";
+// IPC channel is asynchronously set up. So, the NaCl process may try to
+// send a OpenResource message to the host before the connection is
+// established. In such a case, it is necessary to wait for the set up
+// completion.
+class ManifestMessageFilter : public IPC::SyncMessageFilter {
+ public:
+ ManifestMessageFilter(base::WaitableEvent* shutdown_event)
+ : SyncMessageFilter(shutdown_event),
+ connected_event_(
+ true /* manual_reset */, false /* initially_signaled */) {
+ }
+
+ virtual bool Send(IPC::Message* message) OVERRIDE {
+ // Wait until set up is actually done.
+ connected_event_.Wait();
+ return SyncMessageFilter::Send(message);
+ }
+
+ // When set up is done, OnFilterAdded is called on IO thread. Unblocks the
+ // Send().
+ virtual void OnFilterAdded(IPC::Sender* sender) OVERRIDE {
+ SyncMessageFilter::OnFilterAdded(sender);
+ connected_event_.Signal();
+ }
+
+ // If an error is found, unblocks the Send(), too, to return an error.
+ virtual void OnChannelError() OVERRIDE {
+ SyncMessageFilter::OnChannelError();
+ connected_event_.Signal();
+ }
+
+ // Similar to OnChannelError, unblocks the Send() on the channel closing.
+ virtual void OnChannelClosing() OVERRIDE {
+ SyncMessageFilter::OnChannelClosing();
+ connected_event_.Signal();
+ }
+
+ private:
+ base::WaitableEvent connected_event_;
+
+ DISALLOW_COPY_AND_ASSIGN(ManifestMessageFilter);
+};
+
ManifestService::ManifestService(
const IPC::ChannelHandle& handle,
scoped_refptr<base::MessageLoopProxy> io_message_loop,
base::WaitableEvent* shutdown_event) {
- filter_ = new IPC::SyncMessageFilter(shutdown_event);
+ filter_ = new ManifestMessageFilter(shutdown_event);
channel_ = IPC::ChannelProxy::Create(handle,
IPC::Channel::MODE_SERVER,
NULL, // Listener
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698