Commit 6023de86 authored by James Teh's avatar James Teh
Browse files

Bug 1821963 part 4: Remove alertable wait from IPC message loops. r=handyman

This was only ever used by the old accessibility architecture based on content process COM proxies, which is now being removed.

Differential Revision: https://phabricator.services.mozilla.com/D177964
parent cd328c40
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -770,9 +770,6 @@ void ContentChild::Init(mozilla::ipc::UntypedEndpoint&& aEndpoint,
  // If communications with the parent have broken down, take the process
  // down so it's not hanging around.
  GetIPCChannel()->SetAbortOnError(true);
#if defined(XP_WIN) && defined(ACCESSIBILITY)
  GetIPCChannel()->SetChannelFlags(MessageChannel::REQUIRE_A11Y_REENTRY);
#endif

  // This must be checked before any IPDL message, which may hit sentinel
  // errors due to parent and content processes having different
+0 −8
Original line number Diff line number Diff line
@@ -224,11 +224,6 @@ class MessageChannel : HasResultCodes {
    // that manage child processes which might create native UI, like
    // plugins.
    REQUIRE_DEFERRED_MESSAGE_PROTECTION = 1 << 0,
    // Windows: When this flag is specified, any wait that occurs during
    // synchronous IPC will be alertable, thus allowing a11y code in the
    // chrome process to reenter content while content is waiting on a
    // synchronous call.
    REQUIRE_A11Y_REENTRY = 1 << 1,
  };
  void SetChannelFlags(ChannelFlags aFlags) { mFlags = aFlags; }
  ChannelFlags GetChannelFlags() { return mFlags; }
@@ -363,9 +358,6 @@ class MessageChannel : HasResultCodes {

 private:
  void SpinInternalEventLoop();
#  if defined(ACCESSIBILITY)
  bool WaitForSyncNotifyWithA11yReentry();
#  endif  // defined(ACCESSIBILITY)
#endif    // defined(OS_WIN)

 private:
+0 −89
Original line number Diff line number Diff line
@@ -850,88 +850,6 @@ SuppressedNeuteringRegion::~SuppressedNeuteringRegion() {

bool SuppressedNeuteringRegion::sSuppressNeutering = false;

#if defined(ACCESSIBILITY)
static DWORD WaitForSingleObjectExWrapper(HANDLE aEvent, DWORD aTimeout) {
  return ::WaitForSingleObjectEx(aEvent, aTimeout, TRUE);
}

static DWORD CoWaitForMultipleHandlesWrapper(HANDLE aEvent, DWORD aTimeout) {
  DWORD waitResult = 0;
  ::SetLastError(ERROR_SUCCESS);
  HRESULT hr = ::CoWaitForMultipleHandles(COWAIT_ALERTABLE, aTimeout, 1,
                                          &aEvent, &waitResult);
  if (hr == S_OK) {
    return waitResult;
  }
  if (hr == RPC_S_CALLPENDING) {
    return WAIT_TIMEOUT;
  }
  return WAIT_FAILED;
}

bool MessageChannel::WaitForSyncNotifyWithA11yReentry() {
  mMonitor->AssertCurrentThreadOwns();
  MonitorAutoUnlock unlock(*mMonitor);

  static auto* sWaitForEvent = IsWin32kLockedDown()
                                   ? WaitForSingleObjectExWrapper
                                   : CoWaitForMultipleHandlesWrapper;

  const DWORD waitStart = ::GetTickCount();
  DWORD elapsed = 0;
  DWORD timeout =
      mTimeoutMs == kNoTimeout ? INFINITE : static_cast<DWORD>(mTimeoutMs);
  bool timedOut = false;

  while (true) {
    {  // Scope for lock
      MonitorAutoLock lock(*mMonitor);
      if (!Connected()) {
        break;
      }
    }

    if (timeout != static_cast<DWORD>(kNoTimeout)) {
      elapsed = ::GetTickCount() - waitStart;
    }

    if (elapsed >= timeout) {
      timedOut = true;
      break;
    }

    DWORD waitResult = sWaitForEvent(mEvent, timeout - elapsed);

    if (waitResult == WAIT_OBJECT_0) {
      // mEvent is signaled
      BOOL success = ::ResetEvent(mEvent);
      if (!success) {
        gfxDevCrash(mozilla::gfx::LogReason::MessageChannelInvalidHandle)
            << "WindowsMessageChannel::WaitForSyncNotifyWithA11yReentry "
               "failed to reset event. GetLastError: "
            << GetLastError();
      }
      break;
    }

    if (waitResult == WAIT_IO_COMPLETION) {
      // APC fired, keep waiting
      continue;
    }

    if (waitResult == WAIT_TIMEOUT) {
      timeout = true;
      break;
    }

    NS_ERROR("WaitForSyncNotifyWithA11yReentry failed");
    break;
  }

  return WaitResponse(timedOut);
}
#endif

bool MessageChannel::WaitForSyncNotify(bool aHandleWindowsMessages) {
  mMonitor->AssertCurrentThreadOwns();

@@ -939,13 +857,6 @@ bool MessageChannel::WaitForSyncNotify(bool aHandleWindowsMessages) {
    mozilla::ipc::windows::InitUIThread();
  }

#if defined(ACCESSIBILITY)
  if (mFlags & REQUIRE_A11Y_REENTRY) {
    MOZ_ASSERT(!(mFlags & REQUIRE_DEFERRED_MESSAGE_PROTECTION));
    return WaitForSyncNotifyWithA11yReentry();
  }
#endif

  // Use a blocking wait if this channel does not require
  // Windows message deferral behavior.
  if (!(mFlags & REQUIRE_DEFERRED_MESSAGE_PROTECTION) ||
+1 −7
Original line number Diff line number Diff line
@@ -228,15 +228,9 @@ void EnsureMTA::SyncDispatchToPersistentThread(nsIRunnable* aRunnable) {
    return;
  }

#if defined(ACCESSIBILITY)
  const BOOL alertable = XRE_IsContentProcess() && NS_IsMainThread();
#else
  const BOOL alertable = FALSE;
#endif  // defined(ACCESSIBILITY)

  AUTO_PROFILER_THREAD_SLEEP;
  DWORD waitResult;
  while ((waitResult = ::WaitForSingleObjectEx(event, INFINITE, alertable)) ==
  while ((waitResult = ::WaitForSingleObjectEx(event, INFINITE, FALSE)) ==
         WAIT_IO_COMPLETION) {
  }
  MOZ_ASSERT(waitResult == WAIT_OBJECT_0);