Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "content/browser/renderer_host/java/java_bridge_channel_host.h" | 5 #include "content/browser/renderer_host/java/java_bridge_channel_host.h" |
| 6 | 6 |
| 7 #include "base/atomicops.h" | |
| 7 #include "base/lazy_instance.h" | 8 #include "base/lazy_instance.h" |
| 8 #include "base/stringprintf.h" | 9 #include "base/stringprintf.h" |
| 9 #include "base/synchronization/waitable_event.h" | 10 #include "base/synchronization/waitable_event.h" |
| 10 | 11 |
| 11 using base::WaitableEvent; | 12 using base::WaitableEvent; |
| 12 | 13 |
| 13 namespace { | 14 namespace { |
| 14 struct WaitableEventLazyInstanceTraits | 15 struct WaitableEventLazyInstanceTraits |
| 15 : public base::DefaultLazyInstanceTraits<WaitableEvent> { | 16 : public base::DefaultLazyInstanceTraits<WaitableEvent> { |
| 16 static WaitableEvent* New(void* instance) { | 17 static WaitableEvent* New(void* instance) { |
| 17 // Use placement new to initialize our instance in our preallocated space. | 18 // Use placement new to initialize our instance in our preallocated space. |
| 18 // The parenthesis is very important here to force POD type initialization. | 19 // The parenthesis is very important here to force POD type initialization. |
| 19 return new (instance) WaitableEvent(false, false); | 20 return new (instance) WaitableEvent(false, false); |
| 20 } | 21 } |
| 21 }; | 22 }; |
| 22 base::LazyInstance<WaitableEvent, WaitableEventLazyInstanceTraits> dummy_event = | 23 base::LazyInstance<WaitableEvent, WaitableEventLazyInstanceTraits> dummy_event = |
| 23 LAZY_INSTANCE_INITIALIZER; | 24 LAZY_INSTANCE_INITIALIZER; |
| 25 | |
| 26 base::subtle::AtomicWord g_last_id = 0; | |
| 24 } | 27 } |
| 25 | 28 |
| 26 JavaBridgeChannelHost* JavaBridgeChannelHost::GetJavaBridgeChannelHost( | 29 JavaBridgeChannelHost* JavaBridgeChannelHost::GetJavaBridgeChannelHost( |
| 27 int renderer_id, base::MessageLoopProxy* ipc_message_loop) { | 30 int renderer_id, |
| 31 base::MessageLoopProxy* ipc_message_loop) { | |
| 28 std::string channel_name(StringPrintf("r%d.javabridge", renderer_id)); | 32 std::string channel_name(StringPrintf("r%d.javabridge", renderer_id)); |
| 29 // We don't use a shutdown event because the Java Bridge only sends messages | 33 // We don't use a shutdown event because the Java Bridge only sends messages |
| 30 // from renderer to browser, so we'll never be waiting for a sync IPC to | 34 // from renderer to browser, so we'll never be waiting for a sync IPC to |
| 31 // complete. So we use an event which is never signaled. | 35 // complete. So we use an event which is never signaled. |
| 32 return static_cast<JavaBridgeChannelHost*>(NPChannelBase::GetChannel( | 36 return static_cast<JavaBridgeChannelHost*>(NPChannelBase::GetChannel( |
| 33 channel_name, | 37 channel_name, |
| 34 IPC::Channel::MODE_SERVER, | 38 IPC::Channel::MODE_SERVER, |
| 35 ClassFactory, | 39 ClassFactory, |
| 36 ipc_message_loop, | 40 ipc_message_loop, |
| 37 false, | 41 false, |
| 38 dummy_event.Pointer())); | 42 dummy_event.Pointer())); |
| 39 } | 43 } |
| 40 | 44 |
| 45 int JavaBridgeChannelHost::ThreadsafeGenerateRouteID() { | |
| 46 return base::subtle::Barrier_AtomicIncrement(&g_last_id, 1); | |
|
joth
2011/12/08 18:15:46
I'll stick my head out and say NoBarrier is fine h
Steve Block
2011/12/09 12:27:32
Done.
| |
| 47 } | |
| 48 | |
| 41 int JavaBridgeChannelHost::GenerateRouteID() { | 49 int JavaBridgeChannelHost::GenerateRouteID() { |
| 42 static int last_id = 0; | 50 return ThreadsafeGenerateRouteID(); |
| 43 return ++last_id; | |
| 44 } | 51 } |
| 45 | 52 |
| 46 bool JavaBridgeChannelHost::Init(base::MessageLoopProxy* ipc_message_loop, | 53 bool JavaBridgeChannelHost::Init(base::MessageLoopProxy* ipc_message_loop, |
| 47 bool create_pipe_now, | 54 bool create_pipe_now, |
| 48 WaitableEvent* shutdown_event) { | 55 WaitableEvent* shutdown_event) { |
| 49 if (!NPChannelBase::Init(ipc_message_loop, create_pipe_now, shutdown_event)) { | 56 if (!NPChannelBase::Init(ipc_message_loop, create_pipe_now, shutdown_event)) { |
| 50 return false; | 57 return false; |
| 51 } | 58 } |
| 52 | 59 |
| 53 // Finish populating our ChannelHandle. | 60 // Finish populating our ChannelHandle. |
| 54 #if defined(OS_POSIX) | 61 #if defined(OS_POSIX) |
| 55 // Leave the auto-close property at its default value. | 62 // Leave the auto-close property at its default value. |
| 56 channel_handle_.socket.fd = channel_->GetClientFileDescriptor(); | 63 channel_handle_.socket.fd = channel_->GetClientFileDescriptor(); |
| 57 #endif | 64 #endif |
| 58 | 65 |
| 59 return true; | 66 return true; |
| 60 } | 67 } |
| 61 | 68 |
| 62 bool JavaBridgeChannelHost::Send(IPC::Message* msg) { | 69 bool JavaBridgeChannelHost::Send(IPC::Message* msg) { |
| 63 CHECK(!msg->is_sync() && msg->is_reply()) << | 70 CHECK(!msg->is_sync() && msg->is_reply()) << |
| 64 "Java Bridge only sends messages from renderer to browser."; | 71 "Java Bridge only sends messages from renderer to browser."; |
| 65 return NPChannelBase::Send(msg); | 72 return NPChannelBase::Send(msg); |
| 66 } | 73 } |
| OLD | NEW |