diff options
Diffstat (limited to 'chrome')
37 files changed, 245 insertions, 174 deletions
diff --git a/chrome/browser/browser_process.h b/chrome/browser/browser_process.h index 18ce8be..adff28b 100644 --- a/chrome/browser/browser_process.h +++ b/chrome/browser/browser_process.h @@ -36,6 +36,7 @@ class SuspendController; namespace base { class Thread; +class WaitableEvent; } namespace sandbox { class BrokerServices; @@ -128,10 +129,10 @@ class BrowserProcess { ResourceDispatcherHost* rdh = resource_dispatcher_host(); return rdh ? rdh->download_request_manager() : NULL; } +#endif // Returns an event that is signaled when the browser shutdown. - virtual HANDLE shutdown_event() = 0; -#endif + virtual base::WaitableEvent* shutdown_event() = 0; // Returns a reference to the user-data-dir based profiles vector. std::vector<std::wstring>& user_data_dir_profiles() { diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc index 904de03..bccf10b 100644 --- a/chrome/browser/browser_process_impl.cc +++ b/chrome/browser/browser_process_impl.cc @@ -7,6 +7,7 @@ #include "base/command_line.h" #include "base/path_service.h" #include "base/thread.h" +#include "base/waitable_event.h" #include "chrome/browser/automation/automation_provider_list.h" #include "chrome/browser/browser_trial.h" #include "chrome/browser/chrome_thread.h" @@ -127,7 +128,7 @@ BrowserProcessImpl::BrowserProcessImpl(CommandLine& command_line) memory_model_ = MEDIUM_MEMORY_MODEL; } - shutdown_event_ = ::CreateEvent(NULL, TRUE, FALSE, NULL); + shutdown_event_ = new base::WaitableEvent(true, false); } BrowserProcessImpl::~BrowserProcessImpl() { diff --git a/chrome/browser/browser_process_impl.h b/chrome/browser/browser_process_impl.h index 6f51102..3b8732c 100644 --- a/chrome/browser/browser_process_impl.h +++ b/chrome/browser/browser_process_impl.h @@ -167,7 +167,7 @@ class BrowserProcessImpl : public BrowserProcess, public NonThreadSafe { return memory_model_; } - virtual HANDLE shutdown_event() { return shutdown_event_; } + virtual base::WaitableEvent* shutdown_event() { return shutdown_event_; } private: void CreateResourceDispatcherHost(); @@ -242,7 +242,7 @@ class BrowserProcessImpl : public BrowserProcess, public NonThreadSafe { bool using_new_frames_; // An event that notifies when we are shutting-down. - HANDLE shutdown_event_; + base::WaitableEvent* shutdown_event_; DISALLOW_EVIL_CONSTRUCTORS(BrowserProcessImpl); }; diff --git a/chrome/browser/browser_shutdown.cc b/chrome/browser/browser_shutdown.cc index e192688..e0417fa 100644 --- a/chrome/browser/browser_shutdown.cc +++ b/chrome/browser/browser_shutdown.cc @@ -9,6 +9,7 @@ #include "base/path_service.h" #include "base/string_util.h" #include "base/time.h" +#include "base/waitable_event.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/first_run.h" #include "chrome/browser/jankometer.h" @@ -86,7 +87,7 @@ void Shutdown() { DCHECK(g_browser_process); // Notifies we are going away. - ::SetEvent(g_browser_process->shutdown_event()); + g_browser_process->shutdown_event()->Signal(); PluginService* plugin_service = PluginService::GetInstance(); if (plugin_service) { diff --git a/chrome/browser/render_view_host.cc b/chrome/browser/render_view_host.cc index 5ace177..399beee 100644 --- a/chrome/browser/render_view_host.cc +++ b/chrome/browser/render_view_host.cc @@ -8,6 +8,7 @@ #include <vector> #include "base/string_util.h" +#include "base/waitable_event.h" #include "chrome/app/result_codes.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/cross_site_request_manager.h" @@ -74,7 +75,7 @@ RenderViewHost* RenderViewHost::FromID(int render_process_id, RenderViewHost::RenderViewHost(SiteInstance* instance, RenderViewHostDelegate* delegate, int routing_id, - HANDLE modal_dialog_event) + base::WaitableEvent* modal_dialog_event) : RenderWidgetHost(instance->GetProcess(), routing_id), instance_(instance), enable_dom_ui_bindings_(false), @@ -93,9 +94,9 @@ RenderViewHost::RenderViewHost(SiteInstance* instance, DCHECK(instance_); DCHECK(delegate_); if (modal_dialog_event == NULL) - modal_dialog_event = CreateEvent(NULL, TRUE, FALSE, NULL); + modal_dialog_event = new base::WaitableEvent(true, false); - modal_dialog_event_.Set(modal_dialog_event); + modal_dialog_event_.reset(modal_dialog_event); #ifdef CHROME_PERSONALIZATION personalization_ = Personalization::CreateHostPersonalization(this); #endif @@ -134,7 +135,7 @@ bool RenderViewHost::CreateRenderView() { renderer_process_handle = GetCurrentProcess(); BOOL result = DuplicateHandle(GetCurrentProcess(), - modal_dialog_event_.Get(), + modal_dialog_event_->handle(), renderer_process_handle, &modal_dialog_event, SYNCHRONIZE, @@ -498,7 +499,7 @@ void RenderViewHost::JavaScriptMessageBoxClosed(IPC::Message* reply_msg, } if (--modal_dialog_count_ == 0) - ResetEvent(modal_dialog_event_.Get()); + modal_dialog_event_->Reset(); ViewHostMsg_RunJavaScriptMessage::WriteReplyParams(reply_msg, success, prompt); Send(reply_msg); } @@ -509,7 +510,7 @@ void RenderViewHost::ModalHTMLDialogClosed(IPC::Message* reply_msg, StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kUnloadTimeoutMS)); if (--modal_dialog_count_ == 0) - ResetEvent(modal_dialog_event_.Get()); + modal_dialog_event_->Reset(); ViewHostMsg_ShowModalHTMLDialog::WriteReplyParams(reply_msg, json_retval); Send(reply_msg); @@ -742,7 +743,7 @@ void RenderViewHost::Shutdown() { // If we are being run modally (see RunModal), then we need to cleanup. if (run_modal_reply_msg_) { if (--modal_dialog_count_ == 0) - ResetEvent(modal_dialog_event_.Get()); + modal_dialog_event_->Reset(); Send(run_modal_reply_msg_); run_modal_reply_msg_ = NULL; } @@ -753,7 +754,8 @@ void RenderViewHost::OnMsgCreateWindow(int route_id, HANDLE modal_dialog_event) { RenderViewHostDelegate::View* view = delegate_->GetViewDelegate(); if (view) - view->CreateNewWindow(route_id, modal_dialog_event); + view->CreateNewWindow(route_id, + new base::WaitableEvent(modal_dialog_event)); } void RenderViewHost::OnMsgCreateWidget(int route_id, bool activatable) { @@ -781,7 +783,7 @@ void RenderViewHost::OnMsgShowWidget(int route_id, void RenderViewHost::OnMsgRunModal(IPC::Message* reply_msg) { DCHECK(!run_modal_reply_msg_); if (modal_dialog_count_++ == 0) - SetEvent(modal_dialog_event_.Get()); + modal_dialog_event_->Reset(); run_modal_reply_msg_ = reply_msg; // TODO(darin): Bug 1107929: Need to inform our delegate to show this view in @@ -1085,7 +1087,7 @@ void RenderViewHost::OnMsgRunJavaScriptMessage( IPC::Message* reply_msg) { StopHangMonitorTimeout(); if (modal_dialog_count_++ == 0) - SetEvent(modal_dialog_event_.Get()); + modal_dialog_event_->Signal(); bool did_suppress_message = false; delegate_->RunJavaScriptMessage(message, default_prompt, flags, reply_msg, &are_javascript_messages_suppressed_); @@ -1095,7 +1097,7 @@ void RenderViewHost::OnMsgRunBeforeUnloadConfirm(const std::wstring& message, IPC::Message* reply_msg) { StopHangMonitorTimeout(); if (modal_dialog_count_++ == 0) - SetEvent(modal_dialog_event_.Get()); + modal_dialog_event_->Signal(); delegate_->RunBeforeUnloadConfirm(message, reply_msg); } @@ -1104,7 +1106,7 @@ void RenderViewHost::OnMsgShowModalHTMLDialog( IPC::Message* reply_msg) { StopHangMonitorTimeout(); if (modal_dialog_count_++ == 0) - SetEvent(modal_dialog_event_.Get()); + modal_dialog_event_->Signal(); delegate_->ShowModalHTMLDialog(url, width, height, json_arguments, reply_msg); } diff --git a/chrome/browser/render_view_host.h b/chrome/browser/render_view_host.h index f95720e..7b0ef7a 100644 --- a/chrome/browser/render_view_host.h +++ b/chrome/browser/render_view_host.h @@ -8,7 +8,7 @@ #include <string> #include <vector> -#include "base/scoped_handle.h" +#include "base/scoped_ptr.h" #include "chrome/browser/render_view_host_delegate.h" #include "chrome/browser/render_widget_host.h" #include "chrome/common/page_zoom.h" @@ -33,6 +33,10 @@ struct WebDropData; struct WebPreferences; enum WindowOpenDisposition; +namespace base { +class WaitableEvent; +} + namespace gfx { class Point; } @@ -86,7 +90,7 @@ class RenderViewHost : public RenderWidgetHost { explicit RenderViewHost(SiteInstance* instance, RenderViewHostDelegate* delegate, int routing_id, - HANDLE modal_dialog_event); + base::WaitableEvent* modal_dialog_event); virtual ~RenderViewHost(); SiteInstance* site_instance() const { return instance_; } @@ -578,7 +582,7 @@ class RenderViewHost : public RenderWidgetHost { // Handle to an event that's set when the page is showing a modal dialog box // (or equivalent constrained window). The renderer and plugin processes // check this to know if they should pump messages/tasks then. - ScopedHandle modal_dialog_event_; + scoped_ptr<base::WaitableEvent> modal_dialog_event_; // Multiple dialog boxes can be shown before the first one is finished, // so we keep a counter to know when we can reset the modal dialog event. @@ -618,7 +622,7 @@ class RenderViewHostFactory { SiteInstance* instance, RenderViewHostDelegate* delegate, int routing_id, - HANDLE modal_dialog_event) = 0; + base::WaitableEvent* modal_dialog_event) = 0; }; #endif // CHROME_BROWSER_RENDER_VIEW_HOST_H__ diff --git a/chrome/browser/render_view_host_delegate.h b/chrome/browser/render_view_host_delegate.h index 1fd0c41..34aba46 100644 --- a/chrome/browser/render_view_host_delegate.h +++ b/chrome/browser/render_view_host_delegate.h @@ -22,6 +22,10 @@ class WebContents; struct WebDropData; enum WindowOpenDisposition; +namespace base { +class WaitableEvent; +} + namespace IPC { class Message; } @@ -56,7 +60,10 @@ class RenderViewHostDelegate { // // Note: this is not called "CreateWindow" because that will clash with // the Windows function which is actually a #define. - virtual void CreateNewWindow(int route_id, HANDLE modal_dialog_event) = 0; + // + // NOTE: this takes ownership of @modal_dialog_event + virtual void CreateNewWindow(int route_id, + base::WaitableEvent* modal_dialog_event) = 0; // The page is trying to open a new widget (e.g. a select popup). The // widget should be created associated with the given route, but it should diff --git a/chrome/browser/render_view_host_manager.cc b/chrome/browser/render_view_host_manager.cc index f7edacf..622df9e 100644 --- a/chrome/browser/render_view_host_manager.cc +++ b/chrome/browser/render_view_host_manager.cc @@ -15,6 +15,10 @@ #include "chrome/common/chrome_switches.h" #include "chrome/common/notification_service.h" +namespace base { +class WaitableEvent; +} + RenderViewHostManager::RenderViewHostManager( RenderViewHostFactory* render_view_factory, RenderViewHostDelegate* render_view_delegate, @@ -37,7 +41,7 @@ RenderViewHostManager::~RenderViewHostManager() { void RenderViewHostManager::Init(Profile* profile, SiteInstance* site_instance, int routing_id, - HANDLE modal_dialog_event) { + base::WaitableEvent* modal_dialog_event) { // Create a RenderViewHost, once we have an instance. It is important to // immediately give this SiteInstance to a RenderViewHost so that it is // ref counted. @@ -55,7 +59,7 @@ void RenderViewHostManager::Shutdown() { render_view_host_->Shutdown(); render_view_host_ = NULL; } - + RenderViewHost* RenderViewHostManager::Navigate(const NavigationEntry& entry) { RenderViewHost* dest_render_view_host = UpdateRendererStateNavigate(entry); if (!dest_render_view_host) @@ -347,7 +351,7 @@ bool RenderViewHostManager::CreatePendingRenderView(SiteInstance* instance) { RenderViewHost* RenderViewHostManager::CreateRenderViewHost( SiteInstance* instance, int routing_id, - HANDLE modal_dialog_event) { + base::WaitableEvent* modal_dialog_event) { if (render_view_factory_) { return render_view_factory_->CreateRenderViewHost( instance, render_view_delegate_, routing_id, modal_dialog_event); diff --git a/chrome/browser/render_view_host_manager.h b/chrome/browser/render_view_host_manager.h index 3c2f61d..ee0e16b 100644 --- a/chrome/browser/render_view_host_manager.h +++ b/chrome/browser/render_view_host_manager.h @@ -69,7 +69,7 @@ class RenderViewHostManager { void Init(Profile* profile, SiteInstance* site_instance, int routing_id, - HANDLE modal_dialog_event); + base::WaitableEvent* modal_dialog_event); // Schedules all RenderViewHosts for destruction. void Shutdown(); @@ -179,7 +179,7 @@ class RenderViewHostManager { // factory is NULL). RenderViewHost* CreateRenderViewHost(SiteInstance* instance, int routing_id, - HANDLE modal_dialog_event); + base::WaitableEvent* modal_dialog_event); // Replaces the currently shown render_view_host_ with the RenderViewHost in // the field pointed to by |new_render_view_host|, and then NULLs the field. diff --git a/chrome/browser/tab_contents/web_contents.cc b/chrome/browser/tab_contents/web_contents.cc index 77faa55..638d370 100644 --- a/chrome/browser/tab_contents/web_contents.cc +++ b/chrome/browser/tab_contents/web_contents.cc @@ -178,7 +178,7 @@ WebContents::WebContents(Profile* profile, SiteInstance* site_instance, RenderViewHostFactory* render_view_factory, int routing_id, - HANDLE modal_dialog_event) + base::WaitableEvent* modal_dialog_event) : TabContents(TAB_CONTENTS_WEB), view_(new WebContentsViewWin(this)), ALLOW_THIS_IN_INITIALIZER_LIST( diff --git a/chrome/browser/tab_contents/web_contents.h b/chrome/browser/tab_contents/web_contents.h index 7b44e79..86ce3bf 100644 --- a/chrome/browser/tab_contents/web_contents.h +++ b/chrome/browser/tab_contents/web_contents.h @@ -24,6 +24,10 @@ class RenderViewHostFactory; class RenderWidgetHost; class WebContentsView; +namespace base { +class WaitableEvent; +} + // WebContents represents the contents of a tab that shows web pages. It embeds // a RenderViewHost (via RenderViewHostManager) to actually display the page. class WebContents : public TabContents, @@ -41,7 +45,7 @@ class WebContents : public TabContents, SiteInstance* instance, RenderViewHostFactory* render_view_factory, int routing_id, - HANDLE modal_dialog_event); + base::WaitableEvent* modal_dialog_event); static void RegisterUserPrefs(PrefService* prefs); diff --git a/chrome/browser/tab_contents/web_contents_unittest.cc b/chrome/browser/tab_contents/web_contents_unittest.cc index df018c1..fbb3ad6 100644 --- a/chrome/browser/tab_contents/web_contents_unittest.cc +++ b/chrome/browser/tab_contents/web_contents_unittest.cc @@ -82,7 +82,7 @@ class TestRenderViewHost : public RenderViewHost { SiteInstance* instance, RenderViewHostDelegate* delegate, int routing_id, - HANDLE modal_dialog_event) + base::WaitableEvent* modal_dialog_event) : RenderViewHost(instance, delegate, routing_id, modal_dialog_event), is_loading(false), is_created(false), @@ -156,7 +156,7 @@ class TestRenderViewHostFactory : public RenderViewHostFactory { SiteInstance* instance, RenderViewHostDelegate* delegate, int routing_id, - HANDLE modal_dialog_event) { + base::WaitableEvent* modal_dialog_event) { return new TestRenderViewHost( instance, delegate, routing_id, modal_dialog_event); } @@ -217,7 +217,7 @@ class TestWebContents : public WebContents { RenderViewHost* CreateRenderViewHost(SiteInstance* instance, RenderViewHostDelegate* delegate, int routing_id, - HANDLE modal_dialog_event) { + base::WaitableEvent* modal_dialog_event) { return new TestRenderViewHost( instance, delegate, routing_id, modal_dialog_event); } diff --git a/chrome/browser/tab_contents/web_contents_view.cc b/chrome/browser/tab_contents/web_contents_view.cc index d95fd78..c3c8e8b 100644 --- a/chrome/browser/tab_contents/web_contents_view.cc +++ b/chrome/browser/tab_contents/web_contents_view.cc @@ -16,7 +16,8 @@ void WebContentsView::RenderWidgetHostDestroyed(RenderWidgetHost* host) { } } -void WebContentsView::CreateNewWindow(int route_id, HANDLE modal_dialog_event) { +void WebContentsView::CreateNewWindow(int route_id, + base::WaitableEvent* modal_dialog_event) { // Save the created window associated with the route so we can show it later. pending_contents_[route_id] = CreateNewWindowInternal(route_id, modal_dialog_event); diff --git a/chrome/browser/tab_contents/web_contents_view.h b/chrome/browser/tab_contents/web_contents_view.h index 232b449..dc5362c 100644 --- a/chrome/browser/tab_contents/web_contents_view.h +++ b/chrome/browser/tab_contents/web_contents_view.h @@ -24,6 +24,10 @@ class WebContents; struct WebDropData; class WebKeyboardEvent; +namespace base { +class WaitableEvent; +} + // The WebContentsView is an interface that is implemented by the platform- // dependent web contents views. The WebContents uses this interface to talk to // them. View-related messages will also get forwarded directly to this class @@ -152,8 +156,8 @@ class WebContentsView : public RenderViewHostDelegate::View { // created objects so that they can be associated with the given routes. When // they are shown later, we'll look them up again and pass the objects to // the Show functions rather than the route ID. - virtual WebContents* CreateNewWindowInternal(int route_id, - HANDLE modal_dialog_event) = 0; + virtual WebContents* CreateNewWindowInternal + (int route_id, base::WaitableEvent* modal_dialog_event) = 0; virtual RenderWidgetHostView* CreateNewWidgetInternal(int route_id, bool activatable) = 0; virtual void ShowCreatedWindowInternal(WebContents* new_web_contents, @@ -167,7 +171,8 @@ class WebContentsView : public RenderViewHostDelegate::View { // We implement these functions on RenderViewHostDelegate::View directly and // do some book-keeping associated with the request. The request is then // forwarded to *Internal which does platform-specific work. - virtual void CreateNewWindow(int route_id, HANDLE modal_dialog_event); + virtual void CreateNewWindow(int route_id, + base::WaitableEvent* modal_dialog_event); virtual void CreateNewWidget(int route_id, bool activatable); virtual void ShowCreatedWindow(int route_id, WindowOpenDisposition disposition, diff --git a/chrome/browser/tab_contents/web_contents_view_win.cc b/chrome/browser/tab_contents/web_contents_view_win.cc index ab244cc..29af1f6 100644 --- a/chrome/browser/tab_contents/web_contents_view_win.cc +++ b/chrome/browser/tab_contents/web_contents_view_win.cc @@ -326,7 +326,7 @@ void WebContentsViewWin::ShowContextMenu( WebContents* WebContentsViewWin::CreateNewWindowInternal( int route_id, - HANDLE modal_dialog_event) { + base::WaitableEvent* modal_dialog_event) { // Create the new web contents. This will automatically create the new // WebContentsView. In the future, we may want to create the view separately. WebContents* new_contents = diff --git a/chrome/browser/tab_contents/web_contents_view_win.h b/chrome/browser/tab_contents/web_contents_view_win.h index 137674a..a94b601 100644 --- a/chrome/browser/tab_contents/web_contents_view_win.h +++ b/chrome/browser/tab_contents/web_contents_view_win.h @@ -48,7 +48,7 @@ class WebContentsViewWin : public WebContentsView, // Backend implementation of RenderViewHostDelegate::View. virtual WebContents* CreateNewWindowInternal( - int route_id, HANDLE modal_dialog_event); + int route_id, base::WaitableEvent* modal_dialog_event); virtual RenderWidgetHostView* CreateNewWidgetInternal(int route_id, bool activatable); virtual void ShowCreatedWindowInternal(WebContents* new_web_contents, diff --git a/chrome/common/child_process.cc b/chrome/common/child_process.cc index 979418f..539d8a3 100644 --- a/chrome/common/child_process.cc +++ b/chrome/common/child_process.cc @@ -10,13 +10,14 @@ #include "base/basictypes.h" #include "base/command_line.h" #include "base/string_util.h" +#include "base/waitable_event.h" #include "chrome/common/chrome_switches.h" #include "webkit/glue/webkit_glue.h" ChildProcess* ChildProcess::child_process_; MessageLoop* ChildProcess::main_thread_loop_; static base::AtomicRefCount ref_count; -HANDLE ChildProcess::shutdown_event_; +base::WaitableEvent* ChildProcess::shutdown_event_; ChildProcess::ChildProcess() { @@ -51,7 +52,7 @@ void ChildProcess::OnFinalRelease() { main_thread_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask()); } -HANDLE ChildProcess::GetShutDownEvent() { +base::WaitableEvent* ChildProcess::GetShutDownEvent() { return shutdown_event_; } @@ -74,7 +75,7 @@ bool ChildProcess::GlobalInit(const std::wstring &channel_name, main_thread_loop_ = MessageLoop::current(); // An event that will be signalled when we shutdown. - shutdown_event_ = CreateEvent(NULL, TRUE, FALSE, NULL); + shutdown_event_ = new base::WaitableEvent(true, false); child_process_ = factory->Create(channel_name); @@ -92,7 +93,7 @@ void ChildProcess::GlobalCleanup() { // background threads. // For example, in the renderer the RenderThread instances will be able to // notice shutdown before the render process begins waiting for them to exit. - SetEvent(shutdown_event_); + shutdown_event_->Signal(); // Destroy the child process first to force all background threads to // terminate before we bring down other resources. (We null pointers @@ -103,7 +104,7 @@ void ChildProcess::GlobalCleanup() { main_thread_loop_ = NULL; - CloseHandle(shutdown_event_); + delete shutdown_event_; shutdown_event_ = NULL; } diff --git a/chrome/common/child_process.h b/chrome/common/child_process.h index a74205a..4a63efb 100644 --- a/chrome/common/child_process.h +++ b/chrome/common/child_process.h @@ -10,6 +10,9 @@ #include "base/basictypes.h" #include "base/message_loop.h" +namespace base { + class WaitableEvent; +}; class ChildProcess; @@ -53,7 +56,7 @@ class ChildProcess { // up waiting. // For example, see the renderer code used to implement // webkit_glue::GetCookies. - static HANDLE GetShutDownEvent(); + static base::WaitableEvent* GetShutDownEvent(); // You must call Init after creating this object before it will be valid ChildProcess(); @@ -80,7 +83,7 @@ class ChildProcess { // Derived classes can override this to handle any cleanup, called by // GlobalCleanup. virtual void Cleanup() {} - static HANDLE shutdown_event_; + static base::WaitableEvent* shutdown_event_; DISALLOW_EVIL_CONSTRUCTORS(ChildProcess); }; diff --git a/chrome/common/common.scons b/chrome/common/common.scons index 86255d8..c59ca6c 100644 --- a/chrome/common/common.scons +++ b/chrome/common/common.scons @@ -55,6 +55,7 @@ input_files.extend([ 'ipc_channel_proxy.cc', 'ipc_message.cc', 'ipc_message_utils.cc', + 'ipc_sync_channel.cc', 'ipc_sync_message.cc', 'jpeg_codec.cc', 'json_value_serializer.cc', @@ -99,7 +100,6 @@ if env.Bit('windows'): 'gfx/path.cc', 'gfx/text_elider.cc', 'ipc_logging.cc', - 'ipc_sync_channel.cc', 'jstemplate_builder.cc', 'os_exchange_data.cc', 'plugin_messages.cc', diff --git a/chrome/common/ipc_logging.h b/chrome/common/ipc_logging.h index 2736402..567ba84 100644 --- a/chrome/common/ipc_logging.h +++ b/chrome/common/ipc_logging.h @@ -5,13 +5,14 @@ #ifndef CHROME_COMMON_IPC_LOGGING_H_ #define CHROME_COMMON_IPC_LOGGING_H_ -#include "base/lock.h" -#include "base/object_watcher.h" -#include "base/singleton.h" #include "chrome/common/ipc_message.h" // For IPC_MESSAGE_LOG_ENABLED. #ifdef IPC_MESSAGE_LOG_ENABLED +#include "base/lock.h" +#include "base/object_watcher.h" +#include "base/singleton.h" + class MessageLoop; namespace IPC { diff --git a/chrome/common/ipc_message.h b/chrome/common/ipc_message.h index 8163d4f..040a346 100644 --- a/chrome/common/ipc_message.h +++ b/chrome/common/ipc_message.h @@ -11,9 +11,12 @@ #include "base/pickle.h" #include "testing/gtest/include/gtest/gtest_prod.h" +#if defined(OS_WIN) +// TODO(port): IPC message logging hasn't been ported to other platforms yet. #ifndef NDEBUG #define IPC_MESSAGE_LOG_ENABLED #endif +#endif namespace IPC { diff --git a/chrome/common/ipc_sync_channel.cc b/chrome/common/ipc_sync_channel.cc index 45e42d6..4f1e71f 100644 --- a/chrome/common/ipc_sync_channel.cc +++ b/chrome/common/ipc_sync_channel.cc @@ -2,19 +2,24 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <windows.h> - #include "chrome/common/ipc_sync_channel.h" #include "base/lazy_instance.h" #include "base/logging.h" #include "base/thread_local.h" -#include "chrome/common/child_process.h" +#include "base/message_loop.h" +#include "base/waitable_event.h" +#include "base/waitable_event_watcher.h" #include "chrome/common/ipc_logging.h" #include "chrome/common/ipc_sync_message.h" +#if !defined(OS_WIN) +#define INFINITE -1 +#endif + using base::TimeDelta; using base::TimeTicks; +using base::WaitableEvent; namespace IPC { // When we're blocked in a Send(), we need to process incoming synchronous @@ -34,8 +39,6 @@ namespace IPC { // SyncChannel objects on the same thread (since one object can receive a // sync message while another one is blocked). -class SyncChannel::ReceivedSyncMsgQueue; - class SyncChannel::ReceivedSyncMsgQueue : public base::RefCountedThreadSafe<ReceivedSyncMsgQueue> { public: @@ -70,7 +73,7 @@ class SyncChannel::ReceivedSyncMsgQueue : message_queue_.push_back(QueuedMessage(new Message(msg), context)); } - SetEvent(dispatch_event_); + dispatch_event_.Signal(); if (!was_task_pending) { listener_message_loop_->PostTask(FROM_HERE, NewRunnableMethod( this, &ReceivedSyncMsgQueue::DispatchMessagesTask)); @@ -143,7 +146,7 @@ class SyncChannel::ReceivedSyncMsgQueue : } } - HANDLE dispatch_event() { return dispatch_event_; } + WaitableEvent* dispatch_event() { return &dispatch_event_; } MessageLoop* listener_message_loop() { return listener_message_loop_; } // Holds a pointer to the per-thread ReceivedSyncMsgQueue object. @@ -167,9 +170,9 @@ class SyncChannel::ReceivedSyncMsgQueue : // See the comment in SyncChannel::SyncChannel for why this event is created // as manual reset. ReceivedSyncMsgQueue() : - dispatch_event_(CreateEvent(NULL, TRUE, FALSE, NULL)), - task_pending_(false), + dispatch_event_(true, false), listener_message_loop_(MessageLoop::current()), + task_pending_(false), listener_count_(0) { } @@ -181,14 +184,14 @@ class SyncChannel::ReceivedSyncMsgQueue : }; typedef std::deque<QueuedMessage> SyncMessageQueue; - SyncMessageQueue message_queue_; + SyncMessageQueue message_queue_; std::vector<QueuedMessage> received_replies_; // Set when we got a synchronous message that we must respond to as the // sender needs its reply before it can reply to our original synchronous // message. - ScopedHandle dispatch_event_; + WaitableEvent dispatch_event_; MessageLoop* listener_message_loop_; Lock message_lock_; bool task_pending_; @@ -202,10 +205,10 @@ SyncChannel::SyncContext::SyncContext( Channel::Listener* listener, MessageFilter* filter, MessageLoop* ipc_thread, - HANDLE shutdown_event) + WaitableEvent* shutdown_event) : ChannelProxy::Context(listener, filter, ipc_thread), - shutdown_event_(shutdown_event), - received_sync_msgs_(ReceivedSyncMsgQueue::AddContext()){ + received_sync_msgs_(ReceivedSyncMsgQueue::AddContext()), + shutdown_event_(shutdown_event) { } SyncChannel::SyncContext::~SyncContext() { @@ -217,13 +220,13 @@ SyncChannel::SyncContext::~SyncContext() { // we know how to deserialize the reply. Returns a handle that's set when // the reply has arrived. void SyncChannel::SyncContext::Push(SyncMessage* sync_msg) { - // The event is created as manual reset because in between SetEvent and + // The event is created as manual reset because in between Signal and // OnObjectSignalled, another Send can happen which would stop the watcher // from being called. The event would get watched later, when the nested // Send completes, so the event will need to remain set. PendingSyncMsg pending(SyncMessage::GetMessageId(*sync_msg), sync_msg->GetReplyDeserializer(), - CreateEvent(NULL, TRUE, FALSE, NULL)); + new WaitableEvent(true, false)); AutoLock auto_lock(deserializers_lock_); deserializers_.push_back(pending); } @@ -234,7 +237,8 @@ bool SyncChannel::SyncContext::Pop() { AutoLock auto_lock(deserializers_lock_); PendingSyncMsg msg = deserializers_.back(); delete msg.deserializer; - CloseHandle(msg.done_event); + delete msg.done_event; + msg.done_event = NULL; deserializers_.pop_back(); result = msg.send_result; } @@ -250,12 +254,12 @@ bool SyncChannel::SyncContext::Pop() { return result; } -HANDLE SyncChannel::SyncContext::GetSendDoneEvent() { +WaitableEvent* SyncChannel::SyncContext::GetSendDoneEvent() { AutoLock auto_lock(deserializers_lock_); return deserializers_.back().done_event; } -HANDLE SyncChannel::SyncContext::GetDispatchEvent() { +WaitableEvent* SyncChannel::SyncContext::GetDispatchEvent() { return received_sync_msgs_->dispatch_event(); } @@ -274,7 +278,7 @@ bool SyncChannel::SyncContext::TryToUnblockListener(const Message* msg) { deserializers_.back().send_result = deserializers_.back().deserializer-> SerializeOutputParameters(*msg); } - SetEvent(deserializers_.back().done_event); + deserializers_.back().done_event->Signal(); return true; } @@ -327,7 +331,7 @@ void SyncChannel::SyncContext::OnSendTimeout(int message_id) { PendingSyncMessageQueue::iterator iter; for (iter = deserializers_.begin(); iter != deserializers_.end(); iter++) { if (iter->id == message_id) { - SetEvent(iter->done_event); + iter->done_event->Signal(); break; } } @@ -337,11 +341,11 @@ void SyncChannel::SyncContext::CancelPendingSends() { AutoLock auto_lock(deserializers_lock_); PendingSyncMessageQueue::iterator iter; for (iter = deserializers_.begin(); iter != deserializers_.end(); iter++) - SetEvent(iter->done_event); + iter->done_event->Signal(); } -void SyncChannel::SyncContext::OnObjectSignaled(HANDLE object) { - DCHECK(object == shutdown_event_); +void SyncChannel::SyncContext::OnWaitableEventSignaled(WaitableEvent* event) { + DCHECK(event == shutdown_event_); // Process shut down before we can get a reply to a synchronous message. // Cancel pending Send calls, which will end up setting the send done event. CancelPendingSends(); @@ -351,7 +355,8 @@ void SyncChannel::SyncContext::OnObjectSignaled(HANDLE object) { SyncChannel::SyncChannel( const std::wstring& channel_id, Channel::Mode mode, Channel::Listener* listener, MessageFilter* filter, - MessageLoop* ipc_message_loop, bool create_pipe_now, HANDLE shutdown_event) + MessageLoop* ipc_message_loop, bool create_pipe_now, + WaitableEvent* shutdown_event) : ChannelProxy( channel_id, mode, ipc_message_loop, new SyncContext(listener, filter, ipc_message_loop, shutdown_event), @@ -362,7 +367,7 @@ SyncChannel::SyncChannel( // message loop running under it or not, so we wouldn't know whether to // stop or keep watching. So we always watch it, and create the event as // manual reset since the object watcher might otherwise reset the event - // when we're doing a WaitForMultipleObjects. + // when we're doing a WaitMany. dispatch_watcher_.StartWatching(sync_context()->GetDispatchEvent(), this); } @@ -381,7 +386,7 @@ bool SyncChannel::SendWithTimeout(Message* message, int timeout_ms) { // *this* might get deleted in WaitForReply. scoped_refptr<SyncContext> context(sync_context()); - if (WaitForSingleObject(context->shutdown_event(), 0) == WAIT_OBJECT_0) { + if (context->shutdown_event()->IsSignaled()) { delete message; return false; } @@ -390,7 +395,7 @@ bool SyncChannel::SendWithTimeout(Message* message, int timeout_ms) { SyncMessage* sync_msg = static_cast<SyncMessage*>(message); context->Push(sync_msg); int message_id = SyncMessage::GetMessageId(*sync_msg); - HANDLE pump_messages_event = sync_msg->pump_messages_event(); + WaitableEvent* pump_messages_event = sync_msg->pump_messages_event(); ChannelProxy::Send(message); @@ -409,22 +414,25 @@ bool SyncChannel::SendWithTimeout(Message* message, int timeout_ms) { return context->Pop(); } -void SyncChannel::WaitForReply(HANDLE pump_messages_event) { +void SyncChannel::WaitForReply(WaitableEvent* pump_messages_event) { while (true) { - HANDLE objects[] = { sync_context()->GetDispatchEvent(), - sync_context()->GetSendDoneEvent(), - pump_messages_event }; - uint32 count = pump_messages_event ? 3: 2; - DWORD result = WaitForMultipleObjects(count, objects, FALSE, INFINITE); - if (result == WAIT_OBJECT_0) { + WaitableEvent* objects[] = { + sync_context()->GetDispatchEvent(), + sync_context()->GetSendDoneEvent(), + pump_messages_event + }; + + unsigned count = pump_messages_event ? 3: 2; + unsigned result = WaitableEvent::WaitMany(objects, count); + if (result == 0 /* dispatch event */) { // We're waiting for a reply, but we received a blocking synchronous // call. We must process it or otherwise a deadlock might occur. - ResetEvent(sync_context()->GetDispatchEvent()); + sync_context()->GetDispatchEvent()->Reset(); sync_context()->DispatchMessages(); continue; } - if (result == WAIT_OBJECT_0 + 2) + if (result == 2 /* pump_messages_event */) WaitForReplyWithNestedMessageLoop(); // Start a nested message loop. break; @@ -432,7 +440,7 @@ void SyncChannel::WaitForReply(HANDLE pump_messages_event) { } void SyncChannel::WaitForReplyWithNestedMessageLoop() { - HANDLE old_done_event = send_done_watcher_.GetWatchedObject(); + WaitableEvent* old_done_event = send_done_watcher_.GetWatchedEvent(); send_done_watcher_.StopWatching(); send_done_watcher_.StartWatching(sync_context()->GetSendDoneEvent(), this); bool old_state = MessageLoop::current()->NestableTasksAllowed(); @@ -443,17 +451,17 @@ void SyncChannel::WaitForReplyWithNestedMessageLoop() { send_done_watcher_.StartWatching(old_done_event, this); } -void SyncChannel::OnObjectSignaled(HANDLE object) { - HANDLE dispatch_event = sync_context()->GetDispatchEvent(); - if (object == dispatch_event) { +void SyncChannel::OnWaitableEventSignaled(WaitableEvent* event) { + WaitableEvent* dispatch_event = sync_context()->GetDispatchEvent(); + if (event == dispatch_event) { // The call to DispatchMessages might delete this object, so reregister // the object watcher first. - ResetEvent(dispatch_event); + dispatch_event->Reset(); dispatch_watcher_.StartWatching(dispatch_event, this); sync_context()->DispatchMessages(); } else { // We got the reply, timed out or the process shutdown. - DCHECK(object == sync_context()->GetSendDoneEvent()); + DCHECK(event == sync_context()->GetSendDoneEvent()); MessageLoop::current()->Quit(); } } diff --git a/chrome/common/ipc_sync_channel.h b/chrome/common/ipc_sync_channel.h index 6c03745..725fb33 100644 --- a/chrome/common/ipc_sync_channel.h +++ b/chrome/common/ipc_sync_channel.h @@ -5,19 +5,20 @@ #ifndef CHROME_COMMON_IPC_SYNC_SENDER_H__ #define CHROME_COMMON_IPC_SYNC_SENDER_H__ -#include <windows.h> #include <string> #include <deque> #include "base/basictypes.h" #include "base/lock.h" -#include "base/object_watcher.h" #include "base/ref_counted.h" #include "base/scoped_handle.h" +#include "base/waitable_event.h" +#include "base/waitable_event_watcher.h" #include "chrome/common/ipc_channel_proxy.h" namespace IPC { class SyncMessage; +class MessageReplyDeserializer; // This is similar to IPC::ChannelProxy, with the added feature of supporting // sending synchronous messages. @@ -26,12 +27,12 @@ class SyncMessage; // is running and it's used to send a message, then it will use the invalid // message loop pointer to proxy it to the ipc thread. class SyncChannel : public ChannelProxy, - public base::ObjectWatcher::Delegate { + public base::WaitableEventWatcher::Delegate { public: SyncChannel(const std::wstring& channel_id, Channel::Mode mode, Channel::Listener* listener, MessageFilter* filter, MessageLoop* ipc_message_loop, bool create_pipe_now, - HANDLE shutdown_event); + base::WaitableEvent* shutdown_event); ~SyncChannel(); virtual bool Send(Message* message); @@ -50,12 +51,12 @@ class SyncChannel : public ChannelProxy, // can be deleted while it's being used in a different thread. See // ChannelProxy::Context for more information. class SyncContext : public Context, - public base::ObjectWatcher::Delegate { + public base::WaitableEventWatcher::Delegate { public: SyncContext(Channel::Listener* listener, MessageFilter* filter, MessageLoop* ipc_thread, - HANDLE shutdown_event); + base::WaitableEvent* shutdown_event); ~SyncContext(); @@ -69,11 +70,11 @@ class SyncChannel : public ChannelProxy, // Returns an event that's set when the send is complete, timed out or the // process shut down. - HANDLE GetSendDoneEvent(); + base::WaitableEvent* GetSendDoneEvent(); // Returns an event that's set when an incoming message that's not the reply // needs to get dispatched (by calling SyncContext::DispatchMessages). - HANDLE GetDispatchEvent(); + base::WaitableEvent* GetDispatchEvent(); void DispatchMessages(); @@ -86,7 +87,7 @@ class SyncChannel : public ChannelProxy, // times out. void OnSendTimeout(int message_id); - HANDLE shutdown_event() { return shutdown_event_; } + base::WaitableEvent* shutdown_event() { return shutdown_event_; } private: // IPC::ChannelProxy methods that we override. @@ -103,17 +104,18 @@ class SyncChannel : public ChannelProxy, // Cancels all pending Send calls. void CancelPendingSends(); - // ObjectWatcher::Delegate implementation. - virtual void OnObjectSignaled(HANDLE object); + // WaitableEventWatcher::Delegate implementation. + virtual void OnWaitableEventSignaled(base::WaitableEvent* arg); // When sending a synchronous message, this structure contains an object that // knows how to deserialize the response. struct PendingSyncMsg { - PendingSyncMsg(int id, IPC::MessageReplyDeserializer* d, HANDLE e) : + PendingSyncMsg(int id, IPC::MessageReplyDeserializer* d, + base::WaitableEvent* e) : id(id), deserializer(d), done_event(e), send_result(false) { } int id; IPC::MessageReplyDeserializer* deserializer; - HANDLE done_event; + base::WaitableEvent* done_event; bool send_result; }; @@ -123,19 +125,19 @@ class SyncChannel : public ChannelProxy, scoped_refptr<ReceivedSyncMsgQueue> received_sync_msgs_; - HANDLE shutdown_event_; - base::ObjectWatcher shutdown_watcher_; + base::WaitableEvent* shutdown_event_; + base::WaitableEventWatcher shutdown_watcher_; }; private: - // ObjectWatcher::Delegate implementation. - virtual void OnObjectSignaled(HANDLE object); + // WaitableEventWatcher::Delegate implementation. + virtual void OnWaitableEventSignaled(base::WaitableEvent* arg); SyncContext* sync_context() { return reinterpret_cast<SyncContext*>(context()); } // Both these functions wait for a reply, timeout or process shutdown. The // latter one also runs a nested message loop in the meantime. - void WaitForReply(HANDLE pump_messages_event); + void WaitForReply(base::WaitableEvent* pump_messages_event); // Runs a nested message loop until a reply arrives, times out, or the process // shuts down. @@ -144,8 +146,8 @@ class SyncChannel : public ChannelProxy, bool sync_messages_with_no_timeout_allowed_; // Used to signal events between the IPC and listener threads. - base::ObjectWatcher send_done_watcher_; - base::ObjectWatcher dispatch_watcher_; + base::WaitableEventWatcher send_done_watcher_; + base::WaitableEventWatcher dispatch_watcher_; DISALLOW_EVIL_CONSTRUCTORS(SyncChannel); }; diff --git a/chrome/common/ipc_sync_message.cc b/chrome/common/ipc_sync_message.cc index 4a851e5..a07ea15 100644 --- a/chrome/common/ipc_sync_message.cc +++ b/chrome/common/ipc_sync_message.cc @@ -9,8 +9,9 @@ #endif #include <stack> -#include "chrome/common/ipc_sync_message.h" #include "base/logging.h" +#include "base/waitable_event.h" +#include "chrome/common/ipc_sync_message.h" namespace IPC { @@ -20,7 +21,7 @@ uint32 SyncMessage::next_id_ = 0; #if defined(OS_WIN) // TODO(playmobil): reinstantiate once ObjectWatcher is ported. // A dummy handle used by EnableMessagePumping. -HANDLE dummy_event = ::CreateEvent(NULL, TRUE, TRUE, NULL); +base::WaitableEvent* dummy_event = new base::WaitableEvent(true, true); #endif SyncMessage::SyncMessage( @@ -29,11 +30,8 @@ SyncMessage::SyncMessage( PriorityValue priority, MessageReplyDeserializer* deserializer) : Message(routing_id, type, priority), - deserializer_(deserializer) -#if defined(OS_WIN) - // TODO(playmobil): reinstantiate once ObjectWatcher is ported. - , pump_messages_event_(NULL) -#endif + deserializer_(deserializer), + pump_messages_event_(NULL) { set_sync(); set_unblock(true); diff --git a/chrome/common/ipc_sync_message.h b/chrome/common/ipc_sync_message.h index 116e6c7..034de07 100644 --- a/chrome/common/ipc_sync_message.h +++ b/chrome/common/ipc_sync_message.h @@ -12,6 +12,10 @@ #include "base/basictypes.h" #include "chrome/common/ipc_message.h" +namespace base { +class WaitableEvent; +} + namespace IPC { class MessageReplyDeserializer; @@ -26,15 +30,13 @@ class SyncMessage : public Message { // for deleting the deserializer when they're done. MessageReplyDeserializer* GetReplyDeserializer(); -// TODO(playmobil): reimplement on POSIX. -#if defined(OS_WIN) // If this message can cause the receiver to block while waiting for user // input (i.e. by calling MessageBox), then the caller needs to pump window // messages and dispatch asynchronous messages while waiting for the reply. - // If this handle is passed in, then window messages will start being pumped + // If this event is passed in, then window messages will start being pumped // when it's set. Note that this behavior will continue even if the event is - // later reset. The handle must be valid until after the Send call returns. - void set_pump_messages_event(HANDLE event) { + // later reset. The event must be valid until after the Send call returns. + void set_pump_messages_event(base::WaitableEvent* event) { pump_messages_event_ = event; if (event) { header()->flags |= PUMPING_MSGS_BIT; @@ -47,8 +49,9 @@ class SyncMessage : public Message { // or set_pump_messages_event but not both. void EnableMessagePumping(); - HANDLE pump_messages_event() const { return pump_messages_event_; } -#endif // defined(OS_WIN) + base::WaitableEvent* pump_messages_event() const { + return pump_messages_event_; + } // Returns true if the message is a reply to the given request id. static bool IsMessageReplyTo(const Message& msg, int request_id); @@ -73,9 +76,7 @@ class SyncMessage : public Message { static bool WriteSyncHeader(Message* msg, const SyncHeader& header); MessageReplyDeserializer* deserializer_; -#if defined(OS_WIN) - HANDLE pump_messages_event_; -#endif + base::WaitableEvent* pump_messages_event_; static uint32 next_id_; // for generation of unique ids }; diff --git a/chrome/plugin/npobject_proxy.cc b/chrome/plugin/npobject_proxy.cc index 7df4e5c..3c4f811 100644 --- a/chrome/plugin/npobject_proxy.cc +++ b/chrome/plugin/npobject_proxy.cc @@ -4,6 +4,7 @@ #include "chrome/plugin/npobject_proxy.h" +#include "base/waitable_event.h" #include "chrome/common/plugin_messages.h" #include "chrome/common/win_util.h" #include "chrome/plugin/npobject_util.h" @@ -48,7 +49,7 @@ NPObjectProxy::NPObjectProxy( PluginChannelBase* channel, int route_id, void* npobject_ptr, - HANDLE modal_dialog_event) + base::WaitableEvent* modal_dialog_event) : channel_(channel), route_id_(route_id), npobject_ptr_(npobject_ptr), @@ -67,7 +68,7 @@ NPObjectProxy::~NPObjectProxy() { NPObject* NPObjectProxy::Create(PluginChannelBase* channel, int route_id, void* npobject_ptr, - HANDLE modal_dialog_event) { + base::WaitableEvent* modal_dialog_event) { NPObjectWrapper* obj = reinterpret_cast<NPObjectWrapper*>( NPN_CreateObject(0, &npclass_proxy_)); obj->proxy = new NPObjectProxy( @@ -178,7 +179,7 @@ bool NPObjectProxy::NPInvokePrivate(NPP npp, // messages are pumped). msg->set_pump_messages_event(proxy->modal_dialog_event_); - HANDLE modal_dialog_event_handle = proxy->modal_dialog_event_; + base::WaitableEvent* modal_dialog_event_handle = proxy->modal_dialog_event_; proxy->Send(msg); @@ -237,7 +238,7 @@ bool NPObjectProxy::NPGetProperty(NPObject *obj, CreateNPIdentifierParam(name, &name_param); NPVariant_Param param; - HANDLE modal_dialog_event_handle = proxy->modal_dialog_event_; + base::WaitableEvent* modal_dialog_event_handle = proxy->modal_dialog_event_; scoped_refptr<PluginChannelBase> channel(proxy->channel_); proxy->Send(new NPObjectMsg_GetProperty( proxy->route_id(), name_param, ¶m, &result)); @@ -367,7 +368,7 @@ bool NPObjectProxy::NPNEvaluate(NPP npp, // the reasoning behind setting the pump messages event in the sync message. msg->set_pump_messages_event(proxy->modal_dialog_event_); scoped_refptr<PluginChannelBase> channel(proxy->channel_); - HANDLE modal_dialog_event_handle = proxy->modal_dialog_event_; + base::WaitableEvent* modal_dialog_event_handle = proxy->modal_dialog_event_; proxy->Send(msg); // Send may delete proxy. proxy = NULL; diff --git a/chrome/plugin/npobject_proxy.h b/chrome/plugin/npobject_proxy.h index 4157717..dcc4d01 100644 --- a/chrome/plugin/npobject_proxy.h +++ b/chrome/plugin/npobject_proxy.h @@ -16,6 +16,10 @@ class PluginChannelBase; struct NPObject; struct NPVariant_Param; +namespace base { +class WaitableEvent; +} + // When running a plugin in a different process from the renderer, we need to // proxy calls to NPObjects across process boundaries. This happens both ways, // as a plugin can get an NPObject for the window, and a page can get an @@ -29,10 +33,11 @@ class NPObjectProxy : public IPC::Channel::Listener, public: ~NPObjectProxy(); + // modal_dialog_event_ is must be valid for the lifetime of the NPObjectProxy. static NPObject* Create(PluginChannelBase* channel, int route_id, void* npobject_ptr, - HANDLE modal_dialog_event); + base::WaitableEvent* modal_dialog_event); // IPC::Message::Sender implementation: bool Send(IPC::Message* msg); @@ -93,7 +98,7 @@ class NPObjectProxy : public IPC::Channel::Listener, NPObjectProxy(PluginChannelBase* channel, int route_id, void* npobject_ptr, - HANDLE modal_dialog_event); + base::WaitableEvent* modal_dialog_event); // IPC::Channel::Listener implementation: void OnMessageReceived(const IPC::Message& msg); @@ -109,7 +114,7 @@ class NPObjectProxy : public IPC::Channel::Listener, int route_id_; void* npobject_ptr_; scoped_refptr<PluginChannelBase> channel_; - HANDLE modal_dialog_event_; + base::WaitableEvent* modal_dialog_event_; }; #endif // CHROME_PLUGIN_NPOBJECT_PROXY_H_ diff --git a/chrome/plugin/npobject_util.cc b/chrome/plugin/npobject_util.cc index 8936471..f5283f9 100644 --- a/chrome/plugin/npobject_util.cc +++ b/chrome/plugin/npobject_util.cc @@ -200,7 +200,7 @@ void CreateNPVariantParam(const NPVariant& variant, void CreateNPVariant(const NPVariant_Param& param, PluginChannelBase* channel, NPVariant* result, - HANDLE modal_dialog_event) { + base::WaitableEvent* modal_dialog_event) { switch (param.type) { case NPVARIANT_PARAM_VOID: result->type = NPVariantType_Void; diff --git a/chrome/plugin/npobject_util.h b/chrome/plugin/npobject_util.h index cc9347e..ba74a6b 100644 --- a/chrome/plugin/npobject_util.h +++ b/chrome/plugin/npobject_util.h @@ -22,6 +22,9 @@ struct NPIdentifier_Param; struct NPVariant_Param; typedef void *NPIdentifier; +namespace base { +class WaitableEvent; +} // Needs to be called early in the plugin process lifetime, before any // plugin instances are initialized. @@ -52,7 +55,7 @@ void CreateNPVariantParam(const NPVariant& variant, void CreateNPVariant(const NPVariant_Param& param, PluginChannelBase* channel, NPVariant* result, - HANDLE modal_dialog_event); + base::WaitableEvent* modal_dialog_event); // Given a plugin's HWND, returns an event associated with the WebContents // that's set when inside a messagebox. This tells the plugin process that diff --git a/chrome/plugin/webplugin_proxy.cc b/chrome/plugin/webplugin_proxy.cc index 0bd6ed8..bb7ee5c 100644 --- a/chrome/plugin/webplugin_proxy.cc +++ b/chrome/plugin/webplugin_proxy.cc @@ -8,6 +8,7 @@ #include "base/scoped_handle.h" #include "base/shared_memory.h" #include "base/singleton.h" +#include "base/waitable_event.h" #include "chrome/common/gfx/chrome_canvas.h" #include "chrome/common/plugin_messages.h" #include "chrome/common/win_util.h" @@ -47,7 +48,7 @@ WebPluginProxy::WebPluginProxy( FALSE, 0); DCHECK(result) << "Couldn't duplicate the modal dialog handle for the plugin."; - modal_dialog_event_.Set(event); + modal_dialog_event_.reset(new base::WaitableEvent(event)); } WebPluginProxy::~WebPluginProxy() { @@ -121,7 +122,7 @@ NPObject* WebPluginProxy::GetWindowScriptNPObject() { window_npobject_ = NPObjectProxy::Create(channel_, npobject_route_id, npobject_ptr, - modal_dialog_event_.Get()); + modal_dialog_event_.get()); return window_npobject_; } @@ -141,7 +142,7 @@ NPObject* WebPluginProxy::GetPluginElement() { plugin_element_ = NPObjectProxy::Create(channel_, npobject_route_id, npobject_ptr, - modal_dialog_event_.Get()); + modal_dialog_event_.get()); return plugin_element_; } @@ -170,8 +171,9 @@ void WebPluginProxy::ShowModalHTMLDialog(const GURL& url, int width, int height, // Create a new event and set it. This forces us to pump messages while // waiting for a response (which won't come until the dialog is closed). This // avoids a deadlock. - ScopedHandle event(CreateEvent(NULL, FALSE, TRUE, NULL)); - msg->set_pump_messages_event(event); + scoped_ptr<base::WaitableEvent> event( + new base::WaitableEvent(false, true)); + msg->set_pump_messages_event(event.get()); Send(msg); } diff --git a/chrome/plugin/webplugin_proxy.h b/chrome/plugin/webplugin_proxy.h index c2cefc7..7828abf 100644 --- a/chrome/plugin/webplugin_proxy.h +++ b/chrome/plugin/webplugin_proxy.h @@ -8,12 +8,17 @@ #include "base/hash_tables.h" #include "base/ref_counted.h" #include "base/scoped_handle.h" +#include "base/scoped_ptr.h" #include "base/shared_memory.h" #include "base/timer.h" #include "chrome/common/ipc_message.h" #include "chrome/common/chrome_plugin_api.h" #include "webkit/glue/webplugin.h" +namespace base { +class WaitableEvent; +} + class PluginChannel; class WebPluginDelegateImpl; @@ -126,7 +131,7 @@ class WebPluginProxy : public WebPlugin { gfx::Rect damaged_rect_; bool waiting_for_paint_; uint32 cp_browsing_context_; - ScopedHandle modal_dialog_event_; + scoped_ptr<base::WaitableEvent> modal_dialog_event_; // Variables used for desynchronized windowless plugin painting. See note in // webplugin_delegate_proxy.h for how this works. diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc index 311e865..e0108e4 100644 --- a/chrome/renderer/render_thread.cc +++ b/chrome/renderer/render_thread.cc @@ -198,8 +198,10 @@ void RenderThread::OnCreateNewView(HWND parent_hwnd, int32 view_id) { // TODO(darin): once we have a RenderThread per RenderView, this will need to // change to assert that we are not creating more than one view. + base::WaitableEvent* waitable_event = + new base::WaitableEvent(modal_dialog_event); RenderView::Create( - this, parent_hwnd, modal_dialog_event, MSG_ROUTING_NONE, webkit_prefs, + this, parent_hwnd, waitable_event, MSG_ROUTING_NONE, webkit_prefs, new SharedRenderViewCounter(0), view_id); } diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index 708453f..7c85b65 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -197,7 +197,7 @@ RenderView::~RenderView() { RenderView* RenderView::Create( RenderThreadBase* render_thread, HWND parent_hwnd, - HANDLE modal_dialog_event, + base::WaitableEvent* modal_dialog_event, int32 opener_id, const WebPreferences& webkit_prefs, SharedRenderViewCounter* counter, @@ -245,7 +245,7 @@ void RenderView::JSOutOfMemory() { } void RenderView::Init(HWND parent_hwnd, - HANDLE modal_dialog_event, + base::WaitableEvent* modal_dialog_event, int32 opener_id, const WebPreferences& webkit_prefs, SharedRenderViewCounter* counter, @@ -287,7 +287,7 @@ void RenderView::Init(HWND parent_hwnd, } host_window_ = parent_hwnd; - modal_dialog_event_.Set(modal_dialog_event); + modal_dialog_event_.reset(modal_dialog_event); CommandLine command_line; enable_dom_automation_ = @@ -1648,7 +1648,7 @@ bool RenderView::RunJavaScriptMessage(int type, IPC::SyncMessage* msg = new ViewHostMsg_RunJavaScriptMessage( routing_id_, message, default_value, type, &success, result); - msg->set_pump_messages_event(modal_dialog_event_); + msg->set_pump_messages_event(modal_dialog_event_.get()); Send(msg); return success; @@ -1669,7 +1669,7 @@ bool RenderView::RunBeforeUnloadConfirm(WebView* webview, IPC::SyncMessage* msg = new ViewHostMsg_RunBeforeUnloadConfirm( routing_id_, message, &success, &ignored_result); - msg->set_pump_messages_event(modal_dialog_event_); + msg->set_pump_messages_event(modal_dialog_event_.get()); Send(msg); return success; @@ -1716,7 +1716,7 @@ void RenderView::ShowModalHTMLDialog(const GURL& url, int width, int height, IPC::SyncMessage* msg = new ViewHostMsg_ShowModalHTMLDialog( routing_id_, url, width, height, json_arguments, json_retval); - msg->set_pump_messages_event(modal_dialog_event_); + msg->set_pump_messages_event(modal_dialog_event_.get()); Send(msg); } @@ -1803,8 +1803,10 @@ WebView* RenderView::CreateWebView(WebView* webview, bool user_gesture) { // The WebView holds a reference to this new RenderView const WebPreferences& prefs = webview->GetPreferences(); + base::WaitableEvent* waitable_event = + new base::WaitableEvent(modal_dialog_event); RenderView* view = RenderView::Create(render_thread_, - NULL, modal_dialog_event, routing_id_, + NULL, waitable_event, routing_id_, prefs, shared_popup_counter_, routing_id); view->set_opened_by_user_gesture(user_gesture); @@ -1938,7 +1940,7 @@ void RenderView::RunModal(WebWidget* webwidget) { IPC::SyncMessage* msg = new ViewHostMsg_RunModal(routing_id_); - msg->set_pump_messages_event(modal_dialog_event_); + msg->set_pump_messages_event(modal_dialog_event_.get()); Send(msg); } diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index ef0307d..26e3b97 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -48,6 +48,10 @@ class WebPluginDelegate; class WebPluginDelegateProxy; enum WebRequestCachePolicy; +namespace base { +class WaitableEvent; +} + namespace webkit_glue { struct FileUploadData; } @@ -85,7 +89,7 @@ class RenderView : public RenderWidget, static RenderView* Create( RenderThreadBase* render_thread, HWND parent_hwnd, - HANDLE modal_dialog_event, + base::WaitableEvent* modal_dialog_event, // takes ownership int32 opener_id, const WebPreferences& webkit_prefs, SharedRenderViewCounter* counter, @@ -108,8 +112,8 @@ class RenderView : public RenderWidget, return host_window_; } - HANDLE modal_dialog_event() { - return modal_dialog_event_.Get(); + base::WaitableEvent* modal_dialog_event() { + return modal_dialog_event_.get(); } // IPC::Channel::Listener @@ -328,7 +332,7 @@ class RenderView : public RenderWidget, // set to 'MSG_ROUTING_NONE' if the true ID is not yet known. In this case, // CompleteInit must be called later with the true ID. void Init(HWND parent, - HANDLE modal_dialog_event, + base::WaitableEvent* modal_dialog_event, // takes ownership int32 opener_id, const WebPreferences& webkit_prefs, SharedRenderViewCounter* counter, @@ -659,7 +663,7 @@ class RenderView : public RenderWidget, // Handle to an event that's set when the page is showing a modal dialog (or // equivalent constrained window). The renderer and any plugin processes // check this to know if they should pump messages/tasks then. - ScopedHandle modal_dialog_event_; + scoped_ptr<base::WaitableEvent> modal_dialog_event_; // Document width when in print CSS media type. 0 otherwise. int printed_document_width_; diff --git a/chrome/renderer/webplugin_delegate_proxy.cc b/chrome/renderer/webplugin_delegate_proxy.cc index 22ece4b..f4c61a2 100644 --- a/chrome/renderer/webplugin_delegate_proxy.cc +++ b/chrome/renderer/webplugin_delegate_proxy.cc @@ -246,7 +246,7 @@ bool WebPluginDelegateProxy::Initialize(const GURL& url, char** argn, } } params.load_manually = load_manually; - params.modal_dialog_event = render_view_->modal_dialog_event(); + params.modal_dialog_event = render_view_->modal_dialog_event()->handle(); plugin_ = plugin; @@ -571,7 +571,7 @@ bool WebPluginDelegateProxy::HandleEvent(NPEvent* event, WebCursor* cursor) { IPC::SyncMessage* message = new PluginMsg_HandleEvent(instance_id_, *event, &handled, cursor); - message->set_pump_messages_event(modal_loop_pump_messages_event_); + message->set_pump_messages_event(modal_loop_pump_messages_event_.get()); Send(message); return handled; } @@ -587,7 +587,7 @@ void WebPluginDelegateProxy::OnSetWindow( plugin_->SetWindow(window, modal_loop_pump_messages_event); DCHECK(modal_loop_pump_messages_event_ == NULL); - modal_loop_pump_messages_event_.Set(modal_loop_pump_messages_event); + modal_loop_pump_messages_event_.reset(); } void WebPluginDelegateProxy::OnCancelResource(int id) { diff --git a/chrome/renderer/webplugin_delegate_proxy.h b/chrome/renderer/webplugin_delegate_proxy.h index 4f8b757..521b763 100644 --- a/chrome/renderer/webplugin_delegate_proxy.h +++ b/chrome/renderer/webplugin_delegate_proxy.h @@ -23,6 +23,10 @@ struct PluginHostMsg_RouteToFrame_Params; class RenderView; class SkBitmap; +namespace base { +class WaitableEvent; +} + namespace skia { class PlatformCanvasWin; } @@ -167,7 +171,7 @@ class WebPluginDelegateProxy : public WebPluginDelegate, // Event passed in by the plugin process and is used to decide if // messages need to be pumped in the NPP_HandleEvent sync call. - ScopedHandle modal_loop_pump_messages_event_; + scoped_ptr<base::WaitableEvent> modal_loop_pump_messages_event_; // Bitmap for crashed plugin SkBitmap* sad_plugin_; diff --git a/chrome/test/testing_browser_process.h b/chrome/test/testing_browser_process.h index 4e756f1..76f349c 100644 --- a/chrome/test/testing_browser_process.h +++ b/chrome/test/testing_browser_process.h @@ -15,17 +15,17 @@ #include <string> #include "base/string_util.h" +#include "base/waitable_event.h" #include "chrome/browser/browser_process.h" #include "chrome/common/notification_service.h" #include "base/logging.h" class TestingBrowserProcess : public BrowserProcess { public: - TestingBrowserProcess() { -#if defined(OS_WIN) - shutdown_event_ = ::CreateEvent(NULL, TRUE, FALSE, NULL); -#endif + TestingBrowserProcess() + : shutdown_event_(new base::WaitableEvent(true, false)) { } + virtual ~TestingBrowserProcess() { } @@ -122,15 +122,11 @@ class TestingBrowserProcess : public BrowserProcess { virtual MemoryModel memory_model() { return HIGH_MEMORY_MODEL; } -#if defined(OS_WIN) - virtual HANDLE shutdown_event() { return shutdown_event_; } -#endif + virtual base::WaitableEvent* shutdown_event() { return shutdown_event_.get(); } private: NotificationService notification_service_; -#if defined(OS_WIN) - HANDLE shutdown_event_; -#endif + scoped_ptr<base::WaitableEvent> shutdown_event_; DISALLOW_COPY_AND_ASSIGN(TestingBrowserProcess); }; |