Bug 1277705 - Remove waitable_event_watcher (r=dvander)
authorBill McCloskey <billm@mozilla.com>
Wed, 01 Jun 2016 16:31:49 -0700
changeset 332587 28f7e0062d7fe8374825270dc8c6820f114af06a
parent 332586 6e87508415b2c8ded085fb678d9714792bd3ce5f
child 332588 678e3b86d9ee023d4dc38d08693c78cd42621a18
push idunknown
push userunknown
push dateunknown
reviewersdvander
bugs1277705
milestone50.0a1
Bug 1277705 - Remove waitable_event_watcher (r=dvander)
dom/media/gmp/GMPProcessParent.h
dom/plugins/ipc/PluginProcessParent.h
ipc/chromium/moz.build
ipc/chromium/src/base/waitable_event.h
ipc/chromium/src/base/waitable_event_watcher.h
ipc/chromium/src/base/waitable_event_watcher_posix.cc
ipc/chromium/src/base/waitable_event_watcher_win.cc
ipc/chromium/src/base/waitable_event_win.cc
ipc/chromium/src/chrome/common/child_process.cc
ipc/chromium/src/chrome/common/child_process.h
ipc/chromium/src/chrome/common/child_process_host.cc
ipc/chromium/src/chrome/common/child_process_host.h
ipc/glue/GeckoChildProcessHost.cpp
ipc/glue/GeckoChildProcessHost.h
--- a/dom/media/gmp/GMPProcessParent.h
+++ b/dom/media/gmp/GMPProcessParent.h
@@ -6,17 +6,16 @@
 
 #ifndef GMPProcessParent_h
 #define GMPProcessParent_h 1
 
 #include "mozilla/Attributes.h"
 #include "base/basictypes.h"
 #include "base/file_path.h"
 #include "base/thread.h"
-#include "base/waitable_event.h"
 #include "chrome/common/child_process_host.h"
 #include "mozilla/ipc/GeckoChildProcessHost.h"
 
 class nsIRunnable;
 
 namespace mozilla {
 namespace gmp {
 
@@ -30,17 +29,16 @@ public:
   // after timeoutMs, this method will return false.
   bool Launch(int32_t aTimeoutMs);
 
   void Delete(nsCOMPtr<nsIRunnable> aCallback = nullptr);
 
   bool CanShutdown() override { return true; }
   const std::string& GetPluginFilePath() { return mGMPPath; }
 
-  using mozilla::ipc::GeckoChildProcessHost::GetShutDownEvent;
   using mozilla::ipc::GeckoChildProcessHost::GetChannel;
   using mozilla::ipc::GeckoChildProcessHost::GetChildProcessHandle;
 
 private:
   void DoDelete();
 
   std::string mGMPPath;
   nsCOMPtr<nsIRunnable> mDeletedCallback;
--- a/dom/plugins/ipc/PluginProcessParent.h
+++ b/dom/plugins/ipc/PluginProcessParent.h
@@ -8,17 +8,16 @@
 #define dom_plugins_PluginProcessParent_h 1
 
 #include "mozilla/Attributes.h"
 #include "base/basictypes.h"
 
 #include "base/file_path.h"
 #include "base/task.h"
 #include "base/thread.h"
-#include "base/waitable_event.h"
 #include "chrome/common/child_process_host.h"
 
 #include "mozilla/ipc/GeckoChildProcessHost.h"
 #include "mozilla/ipc/TaskFactory.h"
 #include "mozilla/UniquePtr.h"
 #include "nsCOMPtr.h"
 #include "nsIRunnable.h"
 
@@ -61,17 +60,16 @@ public:
 
     virtual bool CanShutdown() override
     {
         return true;
     }
 
     const std::string& GetPluginFilePath() { return mPluginFilePath; }
 
-    using mozilla::ipc::GeckoChildProcessHost::GetShutDownEvent;
     using mozilla::ipc::GeckoChildProcessHost::GetChannel;
 
     void SetCallRunnableImmediately(bool aCallImmediately);
     virtual bool WaitUntilConnected(int32_t aTimeoutMs = 0) override;
 
     virtual void OnChannelConnected(int32_t peer_pid) override;
     virtual void OnChannelError() override;
 
--- a/ipc/chromium/moz.build
+++ b/ipc/chromium/moz.build
@@ -48,17 +48,16 @@ if os_win:
         'src/base/process_win.cc',
         'src/base/rand_util_win.cc',
         'src/base/shared_memory_win.cc',
         'src/base/sys_info_win.cc',
         'src/base/sys_string_conversions_win.cc',
         'src/base/thread_local_storage_win.cc',
         'src/base/thread_local_win.cc',
         'src/base/time_win.cc',
-        'src/base/waitable_event_watcher_win.cc',
         'src/base/waitable_event_win.cc',
         'src/base/win_util.cc',
         'src/chrome/common/ipc_channel_win.cc',
         'src/chrome/common/process_watcher_win.cc',
         'src/chrome/common/transport_dib_win.cc',
     ]
 elif not CONFIG['MOZ_SYSTEM_LIBEVENT']:
     DIRS += ['src/third_party']
@@ -76,17 +75,16 @@ if os_posix:
         'src/base/process_util_posix.cc',
         'src/base/rand_util_posix.cc',
         'src/base/shared_memory_posix.cc',
         'src/base/string16.cc',
         'src/base/sys_info_posix.cc',
         'src/base/thread_local_posix.cc',
         'src/base/thread_local_storage_posix.cc',
         'src/base/waitable_event_posix.cc',
-        'src/base/waitable_event_watcher_posix.cc',
         'src/chrome/common/file_descriptor_set_posix.cc',
         'src/chrome/common/ipc_channel_posix.cc',
         'src/chrome/common/process_watcher_posix_sigchld.cc',
     ]
 
 if os_macosx:
     UNIFIED_SOURCES += [
         'src/base/chrome_application_mac.mm',
--- a/ipc/chromium/src/base/waitable_event.h
+++ b/ipc/chromium/src/base/waitable_event.h
@@ -49,26 +49,16 @@ class TimeDelta;
 class WaitableEvent {
  public:
   // If manual_reset is true, then to set the event state to non-signaled, a
   // consumer must call the Reset method.  If this parameter is false, then the
   // system automatically resets the event state to non-signaled after a single
   // waiting thread has been released.
   WaitableEvent(bool manual_reset, bool initially_signaled);
 
-#if defined(OS_WIN)
-  // Create a WaitableEvent from an Event HANDLE which has already been
-  // created. This objects takes ownership of the HANDLE and will close it when
-  // deleted.
-  explicit WaitableEvent(HANDLE event_handle);
-
-  // Releases ownership of the handle from this object.
-  HANDLE Release();
-#endif
-
   ~WaitableEvent();
 
   // Put the event in the un-signaled state.
   void Reset();
 
   // Put the event in the signaled state.  Causing any thread blocked on Wait
   // to be woken up.
   void Signal();
deleted file mode 100644
--- a/ipc/chromium/src/base/waitable_event_watcher.h
+++ /dev/null
@@ -1,156 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef BASE_WAITABLE_EVENT_WATCHER_H_
-#define BASE_WAITABLE_EVENT_WATCHER_H_
-
-#include "build/build_config.h"
-
-#if defined(OS_WIN)
-#include "base/object_watcher.h"
-#else
-#include "base/message_loop.h"
-#include "base/waitable_event.h"
-#include "nsAutoPtr.h"
-#endif
-
-namespace base {
-
-class Flag;
-class AsyncWaiter;
-class AsyncCallbackTask;
-class WaitableEvent;
-
-// -----------------------------------------------------------------------------
-// This class provides a way to wait on a WaitableEvent asynchronously.
-//
-// Each instance of this object can be waiting on a single WaitableEvent. When
-// the waitable event is signaled, a callback is made in the thread of a given
-// MessageLoop. This callback can be deleted by deleting the waiter.
-//
-// Typical usage:
-//
-//   class MyClass : public base::WaitableEventWatcher::Delegate {
-//    public:
-//     void DoStuffWhenSignaled(WaitableEvent *waitable_event) {
-//       watcher_.StartWatching(waitable_event, this);
-//     }
-//     virtual void OnWaitableEventSignaled(WaitableEvent* waitable_event) {
-//       // OK, time to do stuff!
-//     }
-//    private:
-//     base::WaitableEventWatcher watcher_;
-//   };
-//
-// In the above example, MyClass wants to "do stuff" when waitable_event
-// becomes signaled. WaitableEventWatcher makes this task easy. When MyClass
-// goes out of scope, the watcher_ will be destroyed, and there is no need to
-// worry about OnWaitableEventSignaled being called on a deleted MyClass
-// pointer.
-//
-// BEWARE: With automatically reset WaitableEvents, a signal may be lost if it
-// occurs just before a WaitableEventWatcher is deleted. There is currently no
-// safe way to stop watching an automatic reset WaitableEvent without possibly
-// missing a signal.
-//
-// NOTE: you /are/ allowed to delete the WaitableEvent while still waiting on
-// it with a Watcher. It will act as if the event was never signaled.
-// -----------------------------------------------------------------------------
-
-class WaitableEventWatcher
-#if defined(OS_POSIX)
-    : public MessageLoop::DestructionObserver
-#endif
-{
- public:
-
-  WaitableEventWatcher();
-  ~WaitableEventWatcher();
-
-  class Delegate {
-   public:
-    virtual ~Delegate() { }
-
-    // -------------------------------------------------------------------------
-    // This is called on the MessageLoop thread when WaitableEvent has been
-    // signaled.
-    //
-    // Note: the event may not be signaled by the time that this function is
-    // called. This indicates only that it has been signaled at some point in
-    // the past.
-    // -------------------------------------------------------------------------
-    virtual void OnWaitableEventSignaled(WaitableEvent* waitable_event) = 0;
-  };
-
-  // ---------------------------------------------------------------------------
-  // When @event is signaled, the given delegate is called on the thread of the
-  // current message loop when StartWatching is called. The delegate is not
-  // deleted.
-  // ---------------------------------------------------------------------------
-  bool StartWatching(WaitableEvent* event, Delegate* delegate);
-
-  // ---------------------------------------------------------------------------
-  // Cancel the current watch. Must be called from the same thread which
-  // started the watch.
-  //
-  // Does nothing if no event is being watched, nor if the watch has completed.
-  // The delegate will *not* be called for the current watch after this
-  // function returns. Since the delegate runs on the same thread as this
-  // function, it cannot be called during this function either.
-  // ---------------------------------------------------------------------------
-  void StopWatching();
-
-  // ---------------------------------------------------------------------------
-  // Return the currently watched event, or NULL if no object is currently being
-  // watched.
-  // ---------------------------------------------------------------------------
-  WaitableEvent* GetWatchedEvent();
-
- private:
-  WaitableEvent* event_;
-
-#if defined(OS_WIN)
-  // ---------------------------------------------------------------------------
-  // The helper class exists because, if WaitableEventWatcher were to inherit
-  // from ObjectWatcher::Delegate, then it couldn't also have an inner class
-  // called Delegate (at least on Windows). Thus this object exists to proxy
-  // the callback function
-  // ---------------------------------------------------------------------------
-  class ObjectWatcherHelper : public ObjectWatcher::Delegate {
-   public:
-    ObjectWatcherHelper(WaitableEventWatcher* watcher);
-
-    // -------------------------------------------------------------------------
-    // Implementation of ObjectWatcher::Delegate
-    // -------------------------------------------------------------------------
-    void OnObjectSignaled(HANDLE h);
-
-   private:
-    WaitableEventWatcher *const watcher_;
-  };
-
-  void OnObjectSignaled();
-
-  Delegate* delegate_;
-  ObjectWatcherHelper helper_;
-  ObjectWatcher watcher_;
-#else
-  // ---------------------------------------------------------------------------
-  // Implementation of MessageLoop::DestructionObserver
-  // ---------------------------------------------------------------------------
-  void WillDestroyCurrentMessageLoop();
-
-  MessageLoop* message_loop_;
-  RefPtr<Flag> cancel_flag_;
-  AsyncWaiter* waiter_;
-  RefPtr<AsyncCallbackTask> callback_task_;
-  RefPtr<WaitableEvent::WaitableEventKernel> kernel_;
-#endif
-};
-
-}  // namespace base
-
-#endif  // BASE_WAITABLE_EVENT_WATCHER_H_
deleted file mode 100644
--- a/ipc/chromium/src/base/waitable_event_watcher_posix.cc
+++ /dev/null
@@ -1,287 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/waitable_event_watcher.h"
-
-#include "base/condition_variable.h"
-#include "base/lock.h"
-#include "base/message_loop.h"
-#include "base/waitable_event.h"
-
-#include "nsISupportsImpl.h"
-#include "nsAutoPtr.h"
-#include "mozilla/Attributes.h"
-
-namespace base {
-
-// -----------------------------------------------------------------------------
-// WaitableEventWatcher (async waits).
-//
-// The basic design is that we add an AsyncWaiter to the wait-list of the event.
-// That AsyncWaiter has a pointer to MessageLoop, and a Task to be posted to it.
-// The MessageLoop ends up running the task, which calls the delegate.
-//
-// Since the wait can be canceled, we have a thread-safe Flag object which is
-// set when the wait has been canceled. At each stage in the above, we check the
-// flag before going onto the next stage. Since the wait may only be canceled in
-// the MessageLoop which runs the Task, we are assured that the delegate cannot
-// be called after canceling...
-
-// -----------------------------------------------------------------------------
-// A thread-safe, reference-counted, write-once flag.
-// -----------------------------------------------------------------------------
-class Flag final {
- public:
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Flag)
-  Flag() { flag_ = false; }
-
-  void Set() {
-    AutoLock locked(lock_);
-    flag_ = true;
-  }
-
-  bool value() const {
-    AutoLock locked(lock_);
-    return flag_;
-  }
-
- protected:
-  ~Flag() {}
- private:
-  mutable Lock lock_;
-  bool flag_;
-};
-
-// -----------------------------------------------------------------------------
-// This is an asynchronous waiter which posts a task to a MessageLoop when
-// fired. An AsyncWaiter may only be in a single wait-list.
-// -----------------------------------------------------------------------------
-class AsyncWaiter final : public WaitableEvent::Waiter {
- public:
-  AsyncWaiter(MessageLoop* message_loop,
-              already_AddRefed<mozilla::Runnable> task, Flag* flag)
-      : message_loop_(message_loop),
-        cb_task_(task),
-        flag_(flag) { }
-
-  bool Fire(WaitableEvent* event) {
-    if (flag_->value()) {
-      // If the callback has been canceled, we don't enqueue the task, we just
-      // delete it instead.
-      cb_task_ = nullptr;
-    } else {
-      message_loop_->PostTask(cb_task_.forget());
-    }
-
-    // We are removed from the wait-list by the WaitableEvent itself. It only
-    // remains to delete ourselves.
-    delete this;
-
-    // We can always return true because an AsyncWaiter is never in two
-    // different wait-lists at the same time.
-    return true;
-  }
-
-  // See StopWatching for discussion
-  bool Compare(void* tag) {
-    return tag == flag_.get();
-  }
-
- private:
-  MessageLoop *const message_loop_;
-  RefPtr<mozilla::Runnable> cb_task_;
-  RefPtr<Flag> flag_;
-};
-
-// -----------------------------------------------------------------------------
-// For async waits we need to make a callback in a MessageLoop thread. We do
-// this by posting this task, which calls the delegate and keeps track of when
-// the event is canceled.
-// -----------------------------------------------------------------------------
-class AsyncCallbackTask : public mozilla::Runnable {
- public:
-  AsyncCallbackTask(Flag* flag, WaitableEventWatcher::Delegate* delegate,
-                    WaitableEvent* event)
-      : flag_(flag),
-        delegate_(delegate),
-        event_(event) {
-  }
-
-  NS_IMETHOD Run() override {
-    // Runs in MessageLoop thread.
-    if (!flag_->value()) {
-      // This is to let the WaitableEventWatcher know that the event has occured
-      // because it needs to be able to return NULL from GetWatchedObject
-      flag_->Set();
-      delegate_->OnWaitableEventSignaled(event_);
-    }
-
-    return NS_OK;
-    // We are deleted by the MessageLoop
-  }
-
- private:
-  RefPtr<Flag> flag_;
-  WaitableEventWatcher::Delegate *const delegate_;
-  WaitableEvent *const event_;
-};
-
-WaitableEventWatcher::WaitableEventWatcher()
-    : event_(NULL),
-      message_loop_(NULL),
-      cancel_flag_(NULL) {
-}
-
-WaitableEventWatcher::~WaitableEventWatcher() {
-  StopWatching();
-}
-
-// -----------------------------------------------------------------------------
-// The Handle is how the user cancels a wait. After deleting the Handle we
-// insure that the delegate cannot be called.
-// -----------------------------------------------------------------------------
-bool WaitableEventWatcher::StartWatching
-    (WaitableEvent* event, WaitableEventWatcher::Delegate* delegate) {
-  MessageLoop *const current_ml = MessageLoop::current();
-  DCHECK(current_ml) << "Cannot create WaitableEventWatcher without a "
-                        "current MessageLoop";
-
-  // A user may call StartWatching from within the callback function. In this
-  // case, we won't know that we have finished watching, expect that the Flag
-  // will have been set in AsyncCallbackTask::Run()
-  if (cancel_flag_.get() && cancel_flag_->value()) {
-    if (message_loop_) {
-      message_loop_->RemoveDestructionObserver(this);
-      message_loop_ = NULL;
-    }
-
-    cancel_flag_ = NULL;
-  }
-
-  DCHECK(!cancel_flag_.get()) << "StartWatching called while still watching";
-
-  cancel_flag_ = new Flag;
-  callback_task_ = new AsyncCallbackTask(cancel_flag_, delegate, event);
-  WaitableEvent::WaitableEventKernel* kernel = event->kernel_.get();
-
-  AutoLock locked(kernel->lock_);
-
-  if (kernel->signaled_) {
-    if (!kernel->manual_reset_)
-      kernel->signaled_ = false;
-
-    // No hairpinning - we can't call the delegate directly here. We have to
-    // enqueue a task on the MessageLoop as normal.
-    RefPtr<AsyncCallbackTask> addrefedTask = callback_task_;
-    current_ml->PostTask(addrefedTask.forget());
-    return true;
-  }
-
-  message_loop_ = current_ml;
-  current_ml->AddDestructionObserver(this);
-
-  event_ = event;
-  kernel_ = kernel;
-  RefPtr<AsyncCallbackTask> addrefedTask = callback_task_;
-  waiter_ = new AsyncWaiter(current_ml, addrefedTask.forget(), cancel_flag_);
-  event->Enqueue(waiter_);
-
-  return true;
-}
-
-void WaitableEventWatcher::StopWatching() {
-  if (message_loop_) {
-    message_loop_->RemoveDestructionObserver(this);
-    message_loop_ = NULL;
-  }
-
-  if (!cancel_flag_.get())  // if not currently watching...
-    return;
-
-  if (cancel_flag_->value()) {
-    // In this case, the event has fired, but we haven't figured that out yet.
-    // The WaitableEvent may have been deleted too.
-    cancel_flag_ = NULL;
-    return;
-  }
-
-  if (!kernel_.get()) {
-    // We have no kernel. This means that we never enqueued a Waiter on an
-    // event because the event was already signaled when StartWatching was
-    // called.
-    //
-    // In this case, a task was enqueued on the MessageLoop and will run.
-    // We set the flag in case the task hasn't yet run. The flag will stop the
-    // delegate getting called. If the task has run then we have the last
-    // reference to the flag and it will be deleted immedately after.
-    cancel_flag_->Set();
-    cancel_flag_ = NULL;
-    return;
-  }
-
-  AutoLock locked(kernel_->lock_);
-  // We have a lock on the kernel. No one else can signal the event while we
-  // have it.
-
-  // We have a possible ABA issue here. If Dequeue was to compare only the
-  // pointer values then it's possible that the AsyncWaiter could have been
-  // fired, freed and the memory reused for a different Waiter which was
-  // enqueued in the same wait-list. We would think that that waiter was our
-  // AsyncWaiter and remove it.
-  //
-  // To stop this, Dequeue also takes a tag argument which is passed to the
-  // virtual Compare function before the two are considered a match. So we need
-  // a tag which is good for the lifetime of this handle: the Flag. Since we
-  // have a reference to the Flag, its memory cannot be reused while this object
-  // still exists. So if we find a waiter with the correct pointer value, and
-  // which shares a Flag pointer, we have a real match.
-  if (kernel_->Dequeue(waiter_, cancel_flag_.get())) {
-    // Case 2: the waiter hasn't been signaled yet; it was still on the wait
-    // list. We've removed it, thus we can delete it and the task (which cannot
-    // have been enqueued with the MessageLoop because the waiter was never
-    // signaled)
-    delete waiter_;
-    callback_task_ = nullptr;
-    cancel_flag_ = NULL;
-    return;
-  }
-
-  // Case 3: the waiter isn't on the wait-list, thus it was signaled. It may
-  // not have run yet, so we set the flag to tell it not to bother enqueuing the
-  // task on the MessageLoop, but to delete it instead. The Waiter deletes
-  // itself once run.
-  cancel_flag_->Set();
-  cancel_flag_ = NULL;
-
-  // If the waiter has already run then the task has been enqueued. If the Task
-  // hasn't yet run, the flag will stop the delegate from getting called. (This
-  // is thread safe because one may only delete a Handle from the MessageLoop
-  // thread.)
-  //
-  // If the delegate has already been called then we have nothing to do. The
-  // task has been deleted by the MessageLoop.
-}
-
-WaitableEvent* WaitableEventWatcher::GetWatchedEvent() {
-  if (!cancel_flag_.get())
-    return NULL;
-
-  if (cancel_flag_->value())
-    return NULL;
-
-  return event_;
-}
-
-// -----------------------------------------------------------------------------
-// This is called when the MessageLoop which the callback will be run it is
-// deleted. We need to cancel the callback as if we had been deleted, but we
-// will still be deleted at some point in the future.
-// -----------------------------------------------------------------------------
-void WaitableEventWatcher::WillDestroyCurrentMessageLoop() {
-  StopWatching();
-}
-
-}  // namespace base
deleted file mode 100644
--- a/ipc/chromium/src/base/waitable_event_watcher_win.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=8 sts=2 et sw=2 tw=80: */
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/waitable_event_watcher.h"
-
-#include "base/compiler_specific.h"
-#include "base/object_watcher.h"
-#include "base/waitable_event.h"
-
-namespace base {
-
-WaitableEventWatcher::ObjectWatcherHelper::ObjectWatcherHelper(
-    WaitableEventWatcher* watcher)
-    : watcher_(watcher) {
-};
-
-void WaitableEventWatcher::ObjectWatcherHelper::OnObjectSignaled(HANDLE h) {
-  watcher_->OnObjectSignaled();
-}
-
-
-WaitableEventWatcher::WaitableEventWatcher()
-    : event_(NULL),
-      ALLOW_THIS_IN_INITIALIZER_LIST(helper_(this)),
-      delegate_(NULL) {
-}
-
-WaitableEventWatcher::~WaitableEventWatcher() {
-}
-
-bool WaitableEventWatcher::StartWatching(WaitableEvent* event,
-                                         Delegate* delegate) {
-  delegate_ = delegate;
-  event_ = event;
-
-  return watcher_.StartWatching(event->handle(), &helper_);
-}
-
-void WaitableEventWatcher::StopWatching() {
-  delegate_ = NULL;
-  event_ = NULL;
-  watcher_.StopWatching();
-}
-
-WaitableEvent* WaitableEventWatcher::GetWatchedEvent() {
-  return event_;
-}
-
-void WaitableEventWatcher::OnObjectSignaled() {
-  WaitableEvent* event = event_;
-  Delegate* delegate = delegate_;
-  event_ = NULL;
-  delegate_ = NULL;
-  DCHECK(event);
-
-  delegate->OnWaitableEventSignaled(event);
-}
-
-}  // namespace base
--- a/ipc/chromium/src/base/waitable_event_win.cc
+++ b/ipc/chromium/src/base/waitable_event_win.cc
@@ -16,31 +16,20 @@ namespace base {
 
 WaitableEvent::WaitableEvent(bool manual_reset, bool signaled)
     : handle_(CreateEvent(NULL, manual_reset, signaled, NULL)) {
   // We're probably going to crash anyways if this is ever NULL, so we might as
   // well make our stack reports more informative by crashing here.
   CHECK(handle_);
 }
 
-WaitableEvent::WaitableEvent(HANDLE handle)
-    : handle_(handle) {
-  CHECK(handle) << "Tried to create WaitableEvent from NULL handle";
-}
-
 WaitableEvent::~WaitableEvent() {
   CloseHandle(handle_);
 }
 
-HANDLE WaitableEvent::Release() {
-  HANDLE rv = handle_;
-  handle_ = INVALID_HANDLE_VALUE;
-  return rv;
-}
-
 void WaitableEvent::Reset() {
   ResetEvent(handle_);
 }
 
 void WaitableEvent::Signal() {
   SetEvent(handle_);
 }
 
--- a/ipc/chromium/src/chrome/common/child_process.cc
+++ b/ipc/chromium/src/chrome/common/child_process.cc
@@ -49,13 +49,8 @@ void ChildProcess::ReleaseProcess() {
   DCHECK(ref_count_);
   DCHECK(child_process_);
   if (--ref_count_)
     return;
 
   if (child_thread_.get())  // null in unittests.
     child_thread_->OnProcessFinalRelease();
 }
-
-base::WaitableEvent* ChildProcess::GetShutDownEvent() {
-  DCHECK(child_process_);
-  return &child_process_->shutdown_event_;
-}
--- a/ipc/chromium/src/chrome/common/child_process.h
+++ b/ipc/chromium/src/chrome/common/child_process.h
@@ -24,27 +24,16 @@ class ChildProcess {
   // Child processes should have an object that derives from this class.  The
   // constructor will return once ChildThread has started.
   explicit ChildProcess(ChildThread* child_thread);
   virtual ~ChildProcess();
 
   // Getter for this process' main thread.
   ChildThread* child_thread() { return child_thread_.get(); }
 
-  // A global event object that is signalled when the main thread's message
-  // loop exits.  This gives background threads a way to observe the main
-  // thread shutting down.  This can be useful when a background thread is
-  // waiting for some information from the browser process.  If the browser
-  // process goes away prematurely, the background thread can at least notice
-  // the child processes's main thread exiting to determine that it should give
-  // up waiting.
-  // For example, see the renderer code used to implement
-  // webkit_glue::GetCookies.
-  base::WaitableEvent* GetShutDownEvent();
-
   // These are used for ref-counting the child process.  The process shuts
   // itself down when the ref count reaches 0.
   // For example, in the renderer process, generally each tab managed by this
   // process will hold a reference to the process, and release when closed.
   void AddRefProcess();
   void ReleaseProcess();
 
   // Getter for the one ChildProcess object for this process.
--- a/ipc/chromium/src/chrome/common/child_process_host.cc
+++ b/ipc/chromium/src/chrome/common/child_process_host.cc
@@ -26,34 +26,23 @@ typedef std::list<ChildProcessHost*> Chi
 }  // namespace
 
 
 
 ChildProcessHost::ChildProcessHost(ProcessType type)
     :
       ChildProcessInfo(type),
       ALLOW_THIS_IN_INITIALIZER_LIST(listener_(this)),
-      opening_channel_(false),
-      process_event_(nullptr) {
+      opening_channel_(false) {
   Singleton<ChildProcessList>::get()->push_back(this);
 }
 
 
 ChildProcessHost::~ChildProcessHost() {
   Singleton<ChildProcessList>::get()->remove(this);
-
-  if (handle()) {
-    watcher_.StopWatching();
-
-#if defined(OS_WIN)
-    // Above call took ownership, so don't want WaitableEvent to assert because
-    // the handle isn't valid anymore.
-    process_event_->Release();
-#endif
-  }
 }
 
 bool ChildProcessHost::CreateChannel() {
   channel_id_ = IPC::Channel::GenerateVerifiedChannelID(std::wstring());
   channel_.reset(new IPC::Channel(
       channel_id_, IPC::Channel::MODE_SERVER, &listener_));
   if (!channel_->Connect())
     return false;
@@ -76,35 +65,29 @@ bool ChildProcessHost::CreateChannel(Fil
 
   opening_channel_ = true;
 
   return true;
 }
 
 void ChildProcessHost::SetHandle(base::ProcessHandle process) {
 #if defined(OS_WIN)
-  process_event_.reset(new base::WaitableEvent(process));
-
   DCHECK(!handle());
   set_handle(process);
-  watcher_.StartWatching(process_event_.get(), this);
 #endif
 }
 
 bool ChildProcessHost::Send(IPC::Message* msg) {
   if (!channel_.get()) {
     delete msg;
     return false;
   }
   return channel_->Send(msg);
 }
 
-void ChildProcessHost::OnWaitableEventSignaled(base::WaitableEvent *event) {
-}
-
 ChildProcessHost::ListenerHook::ListenerHook(ChildProcessHost* host)
     : host_(host) {
 }
 
 void ChildProcessHost::ListenerHook::OnMessageReceived(
     IPC::Message&& msg) {
   host_->OnMessageReceived(mozilla::Move(msg));
 }
--- a/ipc/chromium/src/chrome/common/child_process_host.h
+++ b/ipc/chromium/src/chrome/common/child_process_host.h
@@ -7,33 +7,31 @@
 #ifndef CHROME_COMMON_CHILD_PROCESS_HOST_H_
 #define CHROME_COMMON_CHILD_PROCESS_HOST_H_
 
 #include "build/build_config.h"
 
 #include <list>
 
 #include "base/basictypes.h"
-#include "base/waitable_event_watcher.h"
 #include "chrome/common/child_process_info.h"
 #include "chrome/common/ipc_channel.h"
 #include "mozilla/UniquePtr.h"
 
 namespace mozilla {
 namespace ipc {
 class FileDescriptor;
 }
 }
 
 // Plugins/workers and other child processes that live on the IO thread should
 // derive from this class.
 class ChildProcessHost :
                          public IPC::Message::Sender,
                          public ChildProcessInfo,
-                         public base::WaitableEventWatcher::Delegate,
                          public IPC::Channel::Listener {
  public:
   virtual ~ChildProcessHost();
 
   // ResourceDispatcherHost::Receiver implementation:
   virtual bool Send(IPC::Message* msg);
 
   // The Iterator class allows iteration through either all child processes, or
@@ -74,25 +72,19 @@ class ChildProcessHost :
   // IPC::Channel::Listener implementation:
   virtual void OnMessageReceived(IPC::Message&& msg) { }
   virtual void OnChannelConnected(int32_t peer_pid) { }
   virtual void OnChannelError() { }
 
   bool opening_channel() { return opening_channel_; }
   const std::wstring& channel_id() { return channel_id_; }
 
-  base::WaitableEvent* GetProcessEvent() { return process_event_.get(); }
-
   const IPC::Channel& channel() const { return *channel_; }
   IPC::Channel* channelp() const { return channel_.get(); }
 
- protected:
-  // WaitableEventWatcher::Delegate implementation:
-  virtual void OnWaitableEventSignaled(base::WaitableEvent *event);
-
  private:
   // By using an internal class as the IPC::Channel::Listener, we can intercept
   // OnMessageReceived/OnChannelConnected and do our own processing before
   // calling the subclass' implementation.
   class ListenerHook : public IPC::Channel::Listener {
    public:
     explicit ListenerHook(ChildProcessHost* host);
     virtual void OnMessageReceived(IPC::Message&& msg);
@@ -108,16 +100,11 @@ class ChildProcessHost :
   // True while we're waiting the channel to be opened.
   bool opening_channel_;
 
   // The IPC::Channel.
   mozilla::UniquePtr<IPC::Channel> channel_;
 
   // IPC Channel's id.
   std::wstring channel_id_;
-
-  // Used to watch the child process handle.
-  base::WaitableEventWatcher watcher_;
-
-  mozilla::UniquePtr<base::WaitableEvent> process_event_;
 };
 
 #endif  // CHROME_COMMON_CHILD_PROCESS_HOST_H_
--- a/ipc/glue/GeckoChildProcessHost.cpp
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -97,17 +97,16 @@ GeckoChildProcessHost::GeckoChildProcess
     mProcessType(aProcessType),
     mPrivileges(aPrivileges),
     mMonitor("mozilla.ipc.GeckChildProcessHost.mMonitor"),
     mProcessState(CREATING_CHANNEL),
 #if defined(MOZ_SANDBOX) && defined(XP_WIN)
     mEnableSandboxLogging(false),
     mSandboxLevel(0),
 #endif
-    mDelegate(nullptr),
     mChildProcessHandle(0)
 #if defined(MOZ_WIDGET_COCOA)
   , mChildTask(MACH_PORT_NULL)
 #endif
 {
     MOZ_COUNT_CTOR(GeckoChildProcessHost);
 }
 
@@ -1210,25 +1209,16 @@ void
 GeckoChildProcessHost::GetQueuedMessages(std::queue<IPC::Message>& queue)
 {
   // If this is called off the IO thread, bad things will happen.
   DCHECK(MessageLoopForIO::current());
   swap(queue, mQueue);
   // We expect the next listener to take over processing of our queue.
 }
 
-void
-GeckoChildProcessHost::OnWaitableEventSignaled(base::WaitableEvent *event)
-{
-  if (mDelegate) {
-    mDelegate->OnWaitableEventSignaled(event);
-  }
-  ChildProcessHost::OnWaitableEventSignaled(event);
-}
-
 bool GeckoChildProcessHost::sRunSelfAsContentProc(false);
 
 #ifdef MOZ_NUWA_PROCESS
 
 using mozilla::ipc::GeckoExistingProcessHost;
 using mozilla::ipc::FileDescriptor;
 
 GeckoExistingProcessHost::
--- a/ipc/glue/GeckoChildProcessHost.h
+++ b/ipc/glue/GeckoChildProcessHost.h
@@ -87,26 +87,20 @@ public:
   virtual void OnMessageReceived(IPC::Message&& aMsg);
   virtual void OnChannelError();
   virtual void GetQueuedMessages(std::queue<IPC::Message>& queue);
 
   virtual void InitializeChannel();
 
   virtual bool CanShutdown() { return true; }
 
-  virtual void OnWaitableEventSignaled(base::WaitableEvent *event);
-
   IPC::Channel* GetChannel() {
     return channelp();
   }
 
-  base::WaitableEvent* GetShutDownEvent() {
-    return GetProcessEvent();
-  }
-
   // Returns a "borrowed" handle to the child process - the handle returned
   // by this function must not be closed by the caller.
   ProcessHandle GetChildProcessHandle() {
     return mChildProcessHandle;
   }
 
   GeckoProcessType GetProcessType() {
     return mProcessType;
@@ -169,18 +163,16 @@ protected:
   int32_t mSandboxLevel;
 #endif
 #endif // XP_WIN
 
 #if defined(OS_POSIX)
   base::file_handle_mapping_vector mFileMap;
 #endif
 
-  base::WaitableEventWatcher::Delegate* mDelegate;
-
   ProcessHandle mChildProcessHandle;
 #if defined(OS_MACOSX)
   task_t mChildTask;
 #endif
 
   void OpenPrivilegedHandle(base::ProcessId aPid);
 
 private: