summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authoragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-01-15 22:25:11 +0000
committeragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-01-15 22:25:11 +0000
commit1c4947ffee0b7f5672737b542eb6adf466fcb223 (patch)
treeca2b1631479523a3a397fac842fe0870f422193f /chrome
parentc0ce93d64e2374f29acf2130c5324dc54762f0fa (diff)
downloadchromium_src-1c4947ffee0b7f5672737b542eb6adf466fcb223.zip
chromium_src-1c4947ffee0b7f5672737b542eb6adf466fcb223.tar.gz
chromium_src-1c4947ffee0b7f5672737b542eb6adf466fcb223.tar.bz2
WaitableEvent is the replacement for Windows events. Previously in the code, a HANDLE from CreateEvent was used for signaling, both within a process and across processes.
WaitableEvent is the cross platform replacement for this. To convert: * HANDLE -> base::WaitableEvent* * ScopedHandle -> scoped_ptr<base::WaitableEvent> * CreateEvent -> new base::WaitableEvent * SetEvent -> base::WaitableEvent::Signal * ResetEvent -> base::WaitableEvent::Reset * ObjectWatcher -> base::WaitableEventWatcher * WaitForMultipleObjects -> static base::WaitableEvent::WaitMany ObjectWatcher remains for Windows specific code. WaitableEventWatcher has an identical interface save, * It uses WaitableEvents, not HANDLEs * It returns void from StartWatching and StopWatcher, rather than errors. System internal errors are fatal to the address space IMPORTANT: There are semantic differences between the different platforms. WaitableEvents on Windows are implemented on top of events. Windows events work across process and this is used mostly for modal dialog support. Windows events can be duplicated with DuplicateHandle. On other platforms, WaitableEvent works only within a single process. In the future we shall have to replace the current uses of cross-process events with IPCs. BEWARE: HANDLE, on Windows, is a void *. Since any pointer type coerces to void *, you can pass a WaitableEvent * where a HANDLE is expected without any build-time errors. Review URL: http://codereview.chromium.org/16554 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@8126 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/browser_process.h5
-rw-r--r--chrome/browser/browser_process_impl.cc3
-rw-r--r--chrome/browser/browser_process_impl.h4
-rw-r--r--chrome/browser/browser_shutdown.cc3
-rw-r--r--chrome/browser/render_view_host.cc26
-rw-r--r--chrome/browser/render_view_host.h12
-rw-r--r--chrome/browser/render_view_host_delegate.h9
-rw-r--r--chrome/browser/render_view_host_manager.cc10
-rw-r--r--chrome/browser/render_view_host_manager.h4
-rw-r--r--chrome/browser/tab_contents/web_contents.cc2
-rw-r--r--chrome/browser/tab_contents/web_contents.h6
-rw-r--r--chrome/browser/tab_contents/web_contents_unittest.cc6
-rw-r--r--chrome/browser/tab_contents/web_contents_view.cc3
-rw-r--r--chrome/browser/tab_contents/web_contents_view.h11
-rw-r--r--chrome/browser/tab_contents/web_contents_view_win.cc2
-rw-r--r--chrome/browser/tab_contents/web_contents_view_win.h2
-rw-r--r--chrome/common/child_process.cc11
-rw-r--r--chrome/common/child_process.h7
-rw-r--r--chrome/common/common.scons2
-rw-r--r--chrome/common/ipc_logging.h7
-rw-r--r--chrome/common/ipc_message.h3
-rw-r--r--chrome/common/ipc_sync_channel.cc94
-rw-r--r--chrome/common/ipc_sync_channel.h42
-rw-r--r--chrome/common/ipc_sync_message.cc12
-rw-r--r--chrome/common/ipc_sync_message.h21
-rw-r--r--chrome/plugin/npobject_proxy.cc11
-rw-r--r--chrome/plugin/npobject_proxy.h11
-rw-r--r--chrome/plugin/npobject_util.cc2
-rw-r--r--chrome/plugin/npobject_util.h5
-rw-r--r--chrome/plugin/webplugin_proxy.cc12
-rw-r--r--chrome/plugin/webplugin_proxy.h7
-rw-r--r--chrome/renderer/render_thread.cc4
-rw-r--r--chrome/renderer/render_view.cc18
-rw-r--r--chrome/renderer/render_view.h14
-rw-r--r--chrome/renderer/webplugin_delegate_proxy.cc6
-rw-r--r--chrome/renderer/webplugin_delegate_proxy.h6
-rw-r--r--chrome/test/testing_browser_process.h16
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, &param, &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);
};