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 |