1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #ifndef mozilla_mscom_MainThreadInvoker_h
8 #define mozilla_mscom_MainThreadInvoker_h
9
10 #include "mozilla/AlreadyAddRefed.h"
11 #include "mozilla/Move.h"
12 #include "mozilla/StaticPtr.h"
13 #include "mozilla/TimeStamp.h"
14 #include "nsCOMPtr.h"
15 #include "nsThreadUtils.h"
16
17 #include <windows.h>
18
19 class nsIRunnable;
20
21 namespace mozilla {
22 namespace mscom {
23
24 class MainThreadInvoker {
25 public:
26 MainThreadInvoker();
27
28 bool Invoke(already_AddRefed<nsIRunnable>&& aRunnable);
GetDuration()29 const TimeDuration& GetDuration() const { return mDuration; }
GetTargetThread()30 static HANDLE GetTargetThread() { return sMainThread; }
31
32 private:
33 TimeDuration mDuration;
34
35 static bool InitStatics();
36 static VOID CALLBACK MainThreadAPC(ULONG_PTR aParam);
37
38 static HANDLE sMainThread;
39 };
40
41 template <typename Class, typename... Args>
InvokeOnMainThread(const char * aName,Class * aObject,void (Class::* aMethod)(Args...),Args...aArgs)42 inline bool InvokeOnMainThread(const char* aName, Class* aObject,
43 void (Class::*aMethod)(Args...), Args... aArgs) {
44 nsCOMPtr<nsIRunnable> runnable(NewNonOwningRunnableMethod<Args...>(
45 aName, aObject, aMethod, Forward<Args>(aArgs)...));
46
47 MainThreadInvoker invoker;
48 return invoker.Invoke(runnable.forget());
49 }
50
51 } // namespace mscom
52 } // namespace mozilla
53
54 #endif // mozilla_mscom_MainThreadInvoker_h
55