• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef BASE_WIN_SCOPED_COM_INITIALIZER_H_
6 #define BASE_WIN_SCOPED_COM_INITIALIZER_H_
7 
8 #include <objbase.h>
9 #include <wrl/client.h>
10 
11 #include "base/base_export.h"
12 #include "base/threading/thread_checker.h"
13 #include "base/win/com_init_balancer.h"
14 #include "base/win/scoped_windows_thread_environment.h"
15 
16 namespace base {
17 namespace win {
18 
19 // Initializes COM in the constructor (STA or MTA), and uninitializes COM in the
20 // destructor.
21 //
22 // It is strongly encouraged to block premature uninitialization of the COM
23 // libraries in threads that execute third-party code, as a way to protect
24 // against unbalanced CoInitialize/CoUninitialize pairs.
25 //
26 // WARNING: This should only be used once per thread, ideally scoped to a
27 // similar lifetime as the thread itself.  You should not be using this in
28 // random utility functions that make COM calls -- instead ensure these
29 // functions are running on a COM-supporting thread!
30 class BASE_EXPORT ScopedCOMInitializer : public ScopedWindowsThreadEnvironment {
31  public:
32   // Enum value provided to initialize the thread as an MTA instead of STA.
33   enum SelectMTA { kMTA };
34 
35   // Enum values which enumerates uninitialization modes for the COM library.
36   enum class Uninitialization {
37     // Default value. Used in threads where no third-party code is executed.
38     kAllow,
39 
40     // Blocks premature uninitialization of the COM libraries before going out
41     // of scope. Used in threads where third-party code is executed.
42     kBlockPremature,
43   };
44 
45   // Constructors for STA initialization.
46   explicit ScopedCOMInitializer(
47       Uninitialization uninitialization = Uninitialization::kAllow);
48 
49   // Constructors for MTA initialization.
50   explicit ScopedCOMInitializer(
51       SelectMTA mta,
52       Uninitialization uninitialization = Uninitialization::kAllow);
53 
54   ScopedCOMInitializer(const ScopedCOMInitializer&) = delete;
55   ScopedCOMInitializer& operator=(const ScopedCOMInitializer&) = delete;
56 
57   ~ScopedCOMInitializer() override;
58 
59   // ScopedWindowsThreadEnvironment:
60   bool Succeeded() const override;
61 
62   // Used for testing. Returns the COM balancer's apartment thread ref count.
63   DWORD GetCOMBalancerReferenceCountForTesting() const;
64 
65  private:
66   void Initialize(COINIT init, Uninitialization uninitialization);
67 
68   HRESULT hr_ = S_OK;
69   Microsoft::WRL::ComPtr<internal::ComInitBalancer> com_balancer_;
70   THREAD_CHECKER(thread_checker_);
71 };
72 
73 }  // namespace win
74 }  // namespace base
75 
76 #endif  // BASE_WIN_SCOPED_COM_INITIALIZER_H_
77