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