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_AgileReference_h
8 #define mozilla_mscom_AgileReference_h
9 
10 #include "mozilla/RefPtr.h"
11 
12 #include <objidl.h>
13 
14 namespace mozilla {
15 namespace mscom {
16 
17 /**
18  * This class encapsulates an "agile reference." These are references that
19  * allow you to pass COM interfaces between apartments. When you have an
20  * interface that you would like to pass between apartments, you wrap that
21  * interface in an AgileReference and pass the agile reference instead. Then
22  * you unwrap the interface by calling AgileReference::Resolve.
23  *
24  * Sample usage:
25  *
26  * // In the multithreaded apartment, foo is an IFoo*
27  * auto myAgileRef = MakeUnique<AgileReference>(IID_IFoo, foo);
28  *
29  * // myAgileRef is passed to our main thread, which runs in a single-threaded
30  * // apartment:
31  *
32  * RefPtr<IFoo> foo;
33  * HRESULT hr = myAgileRef->Resolve(IID_IFoo, getter_AddRefs(foo));
34  * // Now foo may be called from the main thread
35  */
36 class AgileReference {
37  public:
38   AgileReference(REFIID aIid, IUnknown* aObject);
39   AgileReference(AgileReference&& aOther);
40 
41   ~AgileReference();
42 
43   explicit operator bool() const { return mAgileRef || mGitCookie; }
44 
45   HRESULT Resolve(REFIID aIid, void** aOutInterface);
46 
47   AgileReference(const AgileReference& aOther) = delete;
48   AgileReference& operator=(const AgileReference& aOther) = delete;
49   AgileReference& operator=(AgileReference&& aOther) = delete;
50 
51  private:
52   IGlobalInterfaceTable* ObtainGit();
53 
54  private:
55   IID mIid;
56   RefPtr<IAgileReference> mAgileRef;
57   DWORD mGitCookie;
58 };
59 
60 }  // namespace mscom
61 }  // namespace mozilla
62 
63 #endif  // mozilla_mscom_AgileReference_h
64