Skip to content

microsoft/wil

master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

Latest commit

…anged (#368)

* Fix malloc spy conflict with CppWinRTAuthoringTests::NotifyPropertyChanged

The CppWinRTAuthoringTests::NotifyPropertyChanged test
did not clean up everything before it exited. This resulted
in COM remaining initialized at process termination, and
that in turn resulted in adverse interactions with the malloc
spy test, since the "emergency cleanup" calls CoTaskMemFree,
and since COM was put into "possible malloc spy" mode, it
tries to take a lock to protect the potential malloc spy.
But that lock no longer exists, since COM has shut down,
and things spiral downhill.

The NotifyPropertyChanged test tries to clean up the
WindowsXamlManager, but it didn't realize that Close()
is an asynchronous call that queues work back to the
current thread's DispatcherQueue for final cleanup.
The old test just returned immediately and never pumped
messages any more, which resulted in the cleanup never
happening.

To ensure we clean up the WindowsXamlManager, we create
our own DispatcherQueue for the XAML work. Since it's
our DispatcherQueue, we can call ShutdownQueueAsync
to clean it up. ShutdownQueueAsync completes when the
queue has shut down, but before the thread uninitializes COM.
We wait for the DispatcherQueue thread to exit, so that we
know for sure that it has definitely uninitialized COM.
Only then do we allow the test to complete.

This cleans up the leaked COM initialization and avoids
a condition crash during "emergency cleanup".

* Need to initialize as MTA to avoid sync wait on STA

* Don't wait indefinitely for DQ to shut down

Let the WFSO do the wait for both the shutdown and the thread exit.

Also check the TryEnqueue just for extra safety.

Now that we fixed test conflict, we can let the XAML test coexist with the mallocspy test.

---------

Co-authored-by: Duncan Horn <40036384+dunhor@users.noreply.github.com>
be13859

Git stats

Files

Permalink
Failed to load latest commit information.

Windows Implementation Libraries (WIL)

Build Status

The Windows Implementation Libraries (WIL) is a header-only C++ library created to make life easier for developers on Windows through readable type-safe C++ interfaces for common Windows coding patterns.

Some things that WIL includes to whet your appetite:

  • include/wil/resource.h (documentation): Smart pointers and auto-releasing resource wrappers to let you manage Windows API HANDLEs, HWNDs, and other resources and resource handles with RAII semantics.
  • include/wil/win32_helpers.h (documentation): Wrappers for API functions that save you the work of manually specifying buffer sizes, calling a function twice to get the needed buffer size and then allocate and pass the right-size buffer, casting or converting between types, and so on.
  • include/wil/registry.h: Type-safe functions to read from, write to, and watch the registry. Also, registry watchers that can call a lambda function or a callback function you provide whenever a certain tree within the Windows registry changes.
  • include/wil/result.h (documentation): Preprocessor macros to help you check for errors from Windows API functions, in many of the myriad ways those errors are reported, and surface them as error codes or C++ exceptions in your code.
  • include/wil/Tracelogging.h: This file contains the convenience macros that enable developers define and log telemetry. These macros use TraceLogging API to log data. This data can be viewed in tools such as Windows Performance Analyzer.

WIL can be used by C++ code that uses C++ exceptions as well as code that uses returned error codes to report errors. All of WIL can be used from user-space Windows code, and some (such as the RAII resource wrappers) can even be used in kernel mode.

Documentation

This project is documented in its GitHub wiki. Feel free to contribute to it!

Consuming WIL

WIL follows the "live at head" philosophy, so you should feel free to consume WIL directly from the GitHub repo however you please: as a GIT submodule, symbolic link, download and copy files, etc. and update to the latest version at your own cadence. Alternatively, WIL is available using a few package managers, mentioned below. These packages will be updated periodically, likely to average around once or twice per month.

Consuming WIL via NuGet

WIL is available on nuget.org under the name Microsoft.Windows.ImplementationLibrary. This package includes the header files under the include directory as well as a .targets file.

Consuming WIL via vcpkg

WIL is also available using vcpkg under the name wil. Instructions for installing packages can be found in the vcpkg GitHub docs. In general, once vcpkg is set up on the system, you can run:

C:\vcpkg> vcpkg install wil:x86-windows
C:\vcpkg> vcpkg install wil:x64-windows

Note that even though WIL is a header-only library, you still need to install the package for all architectures/platforms you wish to use it with. Otherwise, WIL won't be added to the include path for the missing architectures/platforms. Execute vcpkg help triplet for a list of available options.

Building/Testing

Prerequisites

To get started contributing to WIL, first make sure that you have:

If you are doing any non-trivial work, also be sure to have:

  • A recent version of Clang
    • (winget install -i llvm.llvm and select Add LLVM to the system path for all users)

Initial configuration

Once everything is installed (you'll need to restart Terminal if you updated PATH and don't have this 2023 fix), open a VS native command window (e.g. x64 Native Tools Command Prompt for VS 2022 [not Developer Command Prompt for VS2022]).

  • If you are familiar with CMake you can get started building normally.
  • Otherwise, or if you prefer to skip all of the boilerplate, you can use one of the scripts in the scripts directory, like scripts\init.cmd [optional arguments]
    • For example:
      C:\wil> scripts\init.cmd -c clang -g ninja -b debug

To set up IDEs with IntelliSense, see below.

You can execute init.cmd --help for a summary of available options.

Visual Studio setup

To generate a Visual Studio solution with IntelliSense:

C:\wil> scripts\init.cmd -c msvc -g msbuild

That will create a .sln file in the correspondingbuild/ subdirectory. You can also invoke MSBuild directly to build.

You can also get decent IntelliSense just by opening the repo directory in Visual Studio; VS should auto-detect CMake. You'll have to compile and run tests in a terminal window, though.

Inner loop

The scripts use a common directory pattern of build/$(compiler)$(arch)$(type) for the build output root. E.g. build/clang64debug when using Clang as the compiler, x64 as the architecture, and Debug as the build type. It is this directory where you will want to build from.

For example, if you initialized using the command above (scripts\init.cmd -c clang -g ninja -b debug), you can build the tests like so:

C:\wil\build\clang64debug> ninja

Or, if you want to only build a single test (e.g. for improved compile times):

C:\wil\build\clang64debug> ninja witest.noexcept

The output is a number of test executables. If you used the initialization script(s) mentioned above, or if you followed the same directory naming convention of those scripts, you can use the runtests.cmd script, which will execute any test executables that have been built, erroring out - and preserving the exit code - if any test fails. Note that MSBuild will modify the output directory names, so this script is only compatible with using Ninja as the generator.

Build everything

If you are at the tail end of of a change, you can execute the following to get a wide range of coverage:

C:\wil> scripts\init_all.cmd
C:\wil> scripts\build_all.cmd
C:\wil> scripts\runtests.cmd

Note that this will only test for the architecture that corresponds to the command window you opened. You will want to repeat this process for the other architecture (e.g. by using the x86 Native Tools Command Prompt for VS 2022 in addition to x64).

Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com.

When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.