diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /ipc/mscom/EnsureMTA.h | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'ipc/mscom/EnsureMTA.h')
-rw-r--r-- | ipc/mscom/EnsureMTA.h | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/ipc/mscom/EnsureMTA.h b/ipc/mscom/EnsureMTA.h new file mode 100644 index 000000000..1a8331daa --- /dev/null +++ b/ipc/mscom/EnsureMTA.h @@ -0,0 +1,87 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_mscom_EnsureMTA_h +#define mozilla_mscom_EnsureMTA_h + +#include "MainThreadUtils.h" +#include "mozilla/Attributes.h" +#include "mozilla/DebugOnly.h" +#include "mozilla/Function.h" +#include "mozilla/mscom/COMApartmentRegion.h" +#include "mozilla/mscom/Utils.h" +#include "nsCOMPtr.h" +#include "nsIThread.h" +#include "nsThreadUtils.h" + +#include <windows.h> + +namespace mozilla { +namespace mscom { + +// This class is OK to use as a temporary on the stack. +class MOZ_STACK_CLASS EnsureMTA +{ +public: + /** + * This constructor just ensures that the MTA thread is up and running. + */ + EnsureMTA() + { + MOZ_ASSERT(NS_IsMainThread()); + nsCOMPtr<nsIThread> thread = GetMTAThread(); + MOZ_ASSERT(thread); + } + + template <typename FuncT> + EnsureMTA(const FuncT& aClosure) + { + MOZ_ASSERT(NS_IsMainThread()); + if (IsCurrentThreadMTA()) { + // We're already on the MTA, we can run aClosure directly + aClosure(); + return; + } + + // In this case we need to run aClosure on a background thread in the MTA + nsCOMPtr<nsIThread> thread = GetMTAThread(); + MOZ_ASSERT(thread); + + HANDLE event = ::CreateEventW(nullptr, FALSE, FALSE, nullptr); + if (!event) { + return; + } + + auto eventSetter = [&]() -> void { + aClosure(); + ::SetEvent(event); + }; + + nsresult rv = + thread->Dispatch(NS_NewRunnableFunction(eventSetter), NS_DISPATCH_NORMAL); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + if (NS_WARN_IF(NS_FAILED(rv))) { + ::CloseHandle(event); + return; + } + + DWORD waitResult; + while ((waitResult = ::WaitForSingleObjectEx(event, INFINITE, TRUE)) == + WAIT_IO_COMPLETION) { + } + MOZ_ASSERT(waitResult == WAIT_OBJECT_0); + ::CloseHandle(event); + } + +private: + static nsCOMPtr<nsIThread> GetMTAThread(); +}; + +} // namespace mscom +} // namespace mozilla + +#endif // mozilla_mscom_EnsureMTA_h + |