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; |
24 } | 25 } |
25 | 26 |
27 int RouteIDGenerator::GenerateRouteID() const { | |
28 static base::subtle::AtomicWord last_id = 0; | |
joth
2011/12/07 14:49:09
strictly, this is not thread-safe, as we disable g
Steve Block
2011/12/07 16:47:44
Done.
| |
29 return base::subtle::Barrier_AtomicIncrement(&last_id, 1); | |
30 } | |
31 | |
26 JavaBridgeChannelHost* JavaBridgeChannelHost::GetJavaBridgeChannelHost( | 32 JavaBridgeChannelHost* JavaBridgeChannelHost::GetJavaBridgeChannelHost( |
27 int renderer_id, base::MessageLoopProxy* ipc_message_loop) { | 33 int renderer_id, base::MessageLoopProxy* ipc_message_loop, |
34 RouteIDGenerator* route_id_generator) { | |
28 std::string channel_name(StringPrintf("r%d.javabridge", renderer_id)); | 35 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 | 36 // 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 | 37 // 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. | 38 // complete. So we use an event which is never signaled. |
32 return static_cast<JavaBridgeChannelHost*>(NPChannelBase::GetChannel( | 39 JavaBridgeChannelHost* channel = |
33 channel_name, | 40 static_cast<JavaBridgeChannelHost*>(NPChannelBase::GetChannel( |
34 IPC::Channel::MODE_SERVER, | 41 channel_name, |
35 ClassFactory, | 42 IPC::Channel::MODE_SERVER, |
36 ipc_message_loop, | 43 ClassFactory, |
37 false, | 44 ipc_message_loop, |
38 dummy_event.Pointer())); | 45 true, |
46 dummy_event.Pointer())); | |
47 channel->route_id_generator_ = route_id_generator; | |
48 return channel; | |
39 } | 49 } |
40 | 50 |
41 int JavaBridgeChannelHost::GenerateRouteID() { | 51 int JavaBridgeChannelHost::GenerateRouteID() { |
42 static int last_id = 0; | 52 return route_id_generator_->GenerateRouteID(); |
43 return ++last_id; | |
44 } | 53 } |
45 | 54 |
46 bool JavaBridgeChannelHost::Init(base::MessageLoopProxy* ipc_message_loop, | 55 bool JavaBridgeChannelHost::Init(base::MessageLoopProxy* ipc_message_loop, |
47 bool create_pipe_now, | 56 bool create_pipe_now, |
48 WaitableEvent* shutdown_event) { | 57 WaitableEvent* shutdown_event) { |
49 if (!NPChannelBase::Init(ipc_message_loop, create_pipe_now, shutdown_event)) { | 58 if (!NPChannelBase::Init(ipc_message_loop, create_pipe_now, shutdown_event)) { |
50 return false; | 59 return false; |
51 } | 60 } |
52 | 61 |
53 // Finish populating our ChannelHandle. | 62 // Finish populating our ChannelHandle. |
54 #if defined(OS_POSIX) | 63 #if defined(OS_POSIX) |
55 // Leave the auto-close property at its default value. | 64 // Leave the auto-close property at its default value. |
56 channel_handle_.socket.fd = channel_->GetClientFileDescriptor(); | 65 channel_handle_.socket.fd = channel_->GetClientFileDescriptor(); |
57 #endif | 66 #endif |
58 | 67 |
59 return true; | 68 return true; |
60 } | 69 } |
61 | 70 |
62 bool JavaBridgeChannelHost::Send(IPC::Message* msg) { | 71 bool JavaBridgeChannelHost::Send(IPC::Message* msg) { |
63 CHECK(!msg->is_sync() && msg->is_reply()) << | 72 CHECK(!msg->is_sync() && msg->is_reply()) << |
64 "Java Bridge only sends messages from renderer to browser."; | 73 "Java Bridge only sends messages from renderer to browser."; |
65 return NPChannelBase::Send(msg); | 74 return NPChannelBase::Send(msg); |
66 } | 75 } |
OLD | NEW |