[PATCH] Make an RAII initializer for COM on Windows
Aaron Ballman
aaron.ballman at gmail.com
Mon Apr 27 05:52:47 PDT 2015
On Fri, Apr 24, 2015 at 5:39 PM, Zachary Turner <zturner at google.com> wrote:
> Hi aaron.ballman, compnerd,
>
> Patch should be fairly self-explanatory. Implementation is empty on non-Windows platforms, and on Windows platforms simply calls CoInitializeEx and CoUninitialize.
>
> http://reviews.llvm.org/D9267
>
> Files:
> include/llvm/Support/COM.h
> lib/Support/CMakeLists.txt
> lib/Support/COM.cpp
> lib/Support/Unix/COM.inc
> lib/Support/Windows/COM.inc
>
> EMAIL PREFERENCES
> http://reviews.llvm.org/settings/panel/emailpreferences/
In addition to David's suggestion, some minor nits and questions below:
> Index: include/llvm/Support/COM.h
> ===================================================================
> --- /dev/null
> +++ include/llvm/Support/COM.h
> @@ -0,0 +1,35 @@
> +//===- llvm/Support/COM.h ---------------------------------------*- C++ -*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +/// \file
> +///
> +/// Provides a library for accessing COM functionality of the Host OS.
> +///
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef LLVM_SUPPORT_COM_H
> +#define LLVM_SUPPORT_COM_H
> +
> +namespace llvm {
> +namespace sys {
> +
> +enum class COMThreadingMode { ApartmentThreaded, FreeThreaded };
While I know that these are the COM terms, they're pretty
unintelligible for folks who aren't used to COM. While not 100%
accurate, do you think SingleThreaded and MultiThreaded would be more
clear terms?
> +
> +class COMInitializer {
> +public:
> + COMInitializer(COMThreadingMode Threading, bool SpeedOverMemory = false);
Explicit constructor (though not overly important)?
> + ~COMInitializer();
> +
> +private:
> + COMInitializer(const COMInitializer &) = delete;
> + void operator=(const COMInitializer &) = delete;
> +};
> +}
> +}
> +
> +#endif
> Index: lib/Support/CMakeLists.txt
> ===================================================================
> --- lib/Support/CMakeLists.txt
> +++ lib/Support/CMakeLists.txt
> @@ -37,6 +37,7 @@
> BlockFrequency.cpp
> BranchProbability.cpp
> circular_raw_ostream.cpp
> + COM.cpp
> CommandLine.cpp
> Compression.cpp
> ConvertUTF.c
Do we need to do any special magic to ensure Ole32 is linked in, or
have we always linked against that?
> Index: lib/Support/COM.cpp
> ===================================================================
> --- /dev/null
> +++ lib/Support/COM.cpp
> @@ -0,0 +1,24 @@
> +//===-- COM.cpp - Implement COM utility classes -----------------*- C++ -*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +//
> +// This file implements utility classes related to COM.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#include "llvm/Support/COM.h"
> +
> +#include "llvm/Config/config.h"
> +
> +// Include the platform-specific parts of this class.
> +#ifdef LLVM_ON_UNIX
> +#include "Unix/COM.inc"
> +#endif
> +#ifdef LLVM_ON_WIN32
> +#include "Windows/COM.inc"
> +#endif
Use #elseif?
> Index: lib/Support/Unix/COM.inc
> ===================================================================
> --- /dev/null
> +++ lib/Support/Unix/COM.inc
> @@ -0,0 +1,27 @@
> +//===- llvm/Support/Unix/COM.inc - Unix COM Implementation -----*- C++ -*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +//
> +// This file implements the Unix portion of COM support.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +//===----------------------------------------------------------------------===//
> +//=== WARNING: Implementation here must contain only generic UNIX code that
> +//=== is guaranteed to work on *all* UNIX variants.
> +//===----------------------------------------------------------------------===//
> +
> +namespace llvm {
> +namespace sys {
> +
> +COMInitializer::COMInitializer(COMThreadingMode Threading,
> + bool SpeedOverMemory) {}
> +
> +COMInitializer::~COMInitializer() {}
> +}
> +}
> Index: lib/Support/Windows/COM.inc
> ===================================================================
> --- /dev/null
> +++ lib/Support/Windows/COM.inc
> @@ -0,0 +1,41 @@
> +//===- llvm/Support/Windows/COM.inc - Windows COM Implementation *- C++ -*-===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +//
> +// This file implements the Windows portion of COM support.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +//===----------------------------------------------------------------------===//
> +//=== WARNING: Implementation here must contain only generic UNIX code that
> +//=== is guaranteed to work on *all* UNIX variants.
> +//===----------------------------------------------------------------------===//
Can you fix the comments regarding UNIX vs Windows? ;-)
> +
> +// We need to #include <windows.h> directly, and not WindowsSupport.h, because
> +// WindowsSupport.h #defines WIN32_LEAN_AND_MEAN, which will prevent COM headers
> +// from getting included.
> +#include <windows.h>
Do we need *all* of Windows.h though? I would guess that all we would
need is Objbase.h here, and not Windows.h at all.
> +
> +namespace llvm {
> +namespace sys {
> +
> +COMInitializer::COMInitializer(COMThreadingMode Threading,
> + bool SpeedOverMemory) {
> + DWORD Coinit = 0;
> + if (Threading == COMThreadingMode::ApartmentThreaded)
> + Coinit |= COINIT_APARTMENTTHREADED;
> + else
> + Coinit |= COINIT_MULTITHREADED;
> + if (SpeedOverMemory)
> + Coinit |= COINIT_SPEED_OVER_MEMORY;
> + ::CoInitializeEx(nullptr, Coinit);
> +}
> +
> +COMInitializer::~COMInitializer() { ::CoUninitialize(); }
> +}
> +}
>
~Aaron
More information about the llvm-commits
mailing list