<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <updated>2026-10-16T12:07:23Z</updated>
  <generator>https://njump.me</generator>

  <title>Nostr notes by Raymond Chen (Unofficial)</title>
  <author>
    <name>Raymond Chen (Unofficial)</name>
  </author>
  <link rel="self" type="application/atom+xml" href="https://njump.me/npub1lh6zgrexutqcpr2yfqlus46l0egaad03fp59k6dh8wlaf8xmn6rqkty94g.rss" />
  <link href="https://njump.me/npub1lh6zgrexutqcpr2yfqlus46l0egaad03fp59k6dh8wlaf8xmn6rqkty94g" />
  <id>https://njump.me/npub1lh6zgrexutqcpr2yfqlus46l0egaad03fp59k6dh8wlaf8xmn6rqkty94g</id>
  <icon>https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1fa99.png</icon>
  <logo>https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1fa99.png</logo>




  <entry>
    <id>https://njump.me/nevent1qqsf4jqp0lwj3g60mqn08n9ve8aj8qwutp93xu8hzp9sjgjw9lhh4lczyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gv4v4afa</id>
    
      <title type="html">The Microsoft building that was reportedly haunted Earlier this ...</title>
    
    <link rel="alternate" href="https://njump.me/nevent1qqsf4jqp0lwj3g60mqn08n9ve8aj8qwutp93xu8hzp9sjgjw9lhh4lczyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gv4v4afa" />
    <content type="html">
      The Microsoft building that was reportedly haunted&lt;br/&gt;&lt;br/&gt;Earlier this year, Microsoft sold what was known as Building 22, an office building just up the hill from what is now the Overlake Village Station stop on the light rail 2 line.¹ The build was demolished in late June, bring an end to a creepy piece of Microsoft history.&lt;br/&gt;Building 22 began its life in 1982, when construction began on what was then known as the Koll Center Overlake business park. The building was owned and operated by The Koll Company, a commercial real estate company, and was scheduled to be completed in the middle of 1983.&lt;br/&gt;In February 1991, Microsoft purchased the building from Koll, and by July it was occupied by the International Product Group.&lt;br/&gt;During its time as a Microsoft office, Building 22 was believed by many to be haunted. The descriptions ranged from “it was creepy to say the least” to “the ghosts were quite benign” to “those ghosts were no joke”. Evidence included a phenomenon nicknamed “sick building syndrome” that made many people ill, elevator doors opening randomly, unexplained whistling or rattling sounds from the windows, occasional ghost spottings in the hallway, and at least one time that a car’s parking brake failed, causing the empty car to roll down the hill and collide with another car. Did a ghost release the brake? Who knows?&lt;br/&gt;At the time, there was a Group Health hospital complex next door.² Somehow, the story got around that Building 22 had previously served as the morgue³ for the hospital, and I suspect that the ghost stories and the morgue theory developed in tandem. However, research by Microsoft’s own archives team could not find significant evidence that the building was ever a morgue, despite people insisting with certainty that their office was exactly where the morgue used to be.&lt;br/&gt;Haunted or not, the new owners of the building intend to build apartments on the property. Were the ghosts sold with the building? Will the new apartment be haunted? We’ll let the future residents decide.&lt;br/&gt;Bonus chatter: An old Channel 9 video introduces us to Building 22, ghost included.&lt;br/&gt;Bonus bonus chatter: Another morbid reputation that Building 22 had was that it where teams were “sent to die”, meaning that they were transferred to the building as a final stop before the team was disbanded.&lt;br/&gt;Some people nicknamed Building 22 “Hotel California” or “the black hole” because once you were assigned there, it was almost impossible to get out. You might get moved to another building, but somehow you ended up back in 22. One person who managed to escape quipped, “The longest two years of my career were the six months I spent there.”&lt;br/&gt;Part of what contributed to the dreary reputation of Building 22 was that due to the steep slope of the terrain, half of the bottom floor was underground. One person who had an office on the bottom floor said that it was comfortably cool in the summer, but freezing cold in the winter.&lt;br/&gt;Another quirk of the building was that there was bridge from the uphill side directly into the second floor. People on the first floor whose offices were in the shadow of the bridge nicknamed themselves “trolls”.&lt;br/&gt;¹ Not to be confused with “The Village at Overlake Station”, a residential complex about four blocks from Overlake Village Station.&lt;br/&gt;² The property was sold in 2009 and is now the Esterra Park development.&lt;br/&gt;³ An alternate rumor was that the building used to be the psychiatric ward for the hospital, and the room above the atrium was allegedly the padded room for people at risk of hurting themselves. Some people reported hearing screams from the padded room area.&lt;br/&gt;The post The Microsoft building that was reportedly haunted appeared first on The Old New Thing.&lt;br/&gt;&lt;br/&gt;&lt;a href=&#34;https://devblogs.microsoft.com/oldnewthing/20261030-00/?p=112815/&#34;&gt;https://devblogs.microsoft.com/oldnewthing/20261030-00/?p=112815/&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;#building #overlakevillage #koll #villagestation #kollcenter #haunted #kollcompany #another #productgroup #internationalproduct&lt;br/&gt;&lt;br/&gt;#rss #feeds #linksharing #qwibbit
    </content>
    <updated>2026-10-31T10:49:03Z</updated>
  </entry>

  <entry>
    <id>https://njump.me/nevent1qqszj8ldqz0p7r8fulwwuujn7cte849m7fyqmt0yvrrj0azvpwudlyqzyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gv5gv42j</id>
    
      <title type="html">The support case of a customer who said that all they could see ...</title>
    
    <link rel="alternate" href="https://njump.me/nevent1qqszj8ldqz0p7r8fulwwuujn7cte849m7fyqmt0yvrrj0azvpwudlyqzyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gv5gv42j" />
    <content type="html">
      The support case of a customer who said that all they could see was a black screen&lt;br/&gt;&lt;br/&gt;If you hold a PC’s power button for 12 seconds, it will turn off at the hardware level without notifying the operating system. This is a safety feature so that you can turn of the computer even if the operating system’s “Shut down” command isn’t working.&lt;br/&gt;After eight seconds of the power button being held down, the Windows kernel realizes that the user is trying to do a force-power-off of the system, and it quickly takes a kernel dump that can be uploaded to the Windows Error Reporting service the next time you turn the system on. (Sometimes four seconds isn’t enough time to get enough information, and the kernel dump is incomplete. I believe that on Windows Insider builds of Windows, you get a message that says something like “Please let go of the power button so we can collect more information, and then we will turn off the computer.” This gives the kernel more time to finish capturing its kernel dump.)&lt;br/&gt;These emergency kernel dumps are internally classified as “long power button hold” (LPBH) failures. One of the pieces of information recorded in these emergency kernel dumps is whether the screen consists entirely of black pixels. Those failures are sub-classified as “black screen LPBH”, and they go to a special virtual team for analysis. (I happen to be a member of this black screen LPBH team.)&lt;br/&gt;Sometimes the problem is a broken video driver. Sometimes the video driver is doing just fine, but the desktop compositor is just handing black pixels to the video driver. Sometimes the desktop compositor is doing just fine, but nobody is drawing anything to the screen. And those cases are further subdivided further into cases like “there is nobody around to draw anything” or “the person who normally draws stuff is hung.”&lt;br/&gt;Back in the Windows 3.1 days, there was a customer product support call that would today have been classified as a “black screen” bug: The customer reported that they turned on the computer, and Windows started up, but when the logo went away, all they saw was a blank screen.&lt;br/&gt;After some questioning, the customer support engineer put the story together: It turned out that this customer really liked the color black, so they decided to set up a goth theme. They set the wallpaper color to black. They set the title bar color to black. They set the button color to black. They set the window background color to black. They set the window text color to black. Every possible color you could pick in the Colors control panel was set to black.&lt;br/&gt;Once you get yourself into this situation, it’s hard to get out because you can’t see anything.&lt;br/&gt;I don’t know how the customer support engineer fixed the problem, but I’m guessing that they booted into MS-DOS, ran EDIT.COM, and deleted the [colors] section from the win.ini file, thereby returning all the system colors to defaults.&lt;br/&gt;The post The support case of a customer who said that all they could see was a black screen appeared first on The Old New Thing.&lt;br/&gt;&lt;br/&gt;&lt;a href=&#34;https://devblogs.microsoft.com/oldnewthing/20261029-00/?p=112808/&#34;&gt;https://devblogs.microsoft.com/oldnewthing/20261029-00/?p=112808/&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;#black #screen #customer #lpbh #support #windowserror #errorreporting&lt;br/&gt;&lt;br/&gt;#rss #feeds #linksharing #qwibbit
    </content>
    <updated>2026-10-30T07:09:12Z</updated>
  </entry>

  <entry>
    <id>https://njump.me/nevent1qqs2zd9s87tekgfxgzdes7u4p2ddq6r888mva63fds02kjexjjkj68czyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gvw8azeq</id>
    
      <title type="html">C&#43;&#43;/WinRT overcorrection: Using make_self and immediately ...</title>
    
    <link rel="alternate" href="https://njump.me/nevent1qqs2zd9s87tekgfxgzdes7u4p2ddq6r888mva63fds02kjexjjkj68czyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gvw8azeq" />
    <content type="html">
      C&#43;&#43;/WinRT overcorrection: Using make_self and immediately converting it to the projected interface&lt;br/&gt;&lt;br/&gt;In C&#43;&#43;/WinRT, there are two ways of creating objects that you yourself implement.&lt;br/&gt;For the purpose of this discussion, let Impl be the class you wrote that implements a Windows Runtime object. If you are implementing something that was declared in an IDL file, it will be the winrt::Namespace::implementation::ClassName for the instance object or it will be the winrt::Namespace::factory_implementation::ClassName for the factory object. If it wasn’t declared in an IDL file, then it is the class that you manually derived from winrt::implements.&lt;br/&gt;One way to create the object is to use make&amp;lt;Impl&amp;gt;, which creates the implementation object and then returns the Windows Runtime projection version of that object. (If Impl is manually-derived from winrt::implements, the projection is the first implemented interface.)&lt;br/&gt;From that Windows Runtime projection, you can regain access to the implementation object by doing get_self&amp;lt;Impl&amp;gt;(projected), if you want to access things in the implementation object that aren’t exposed in the projection.&lt;br/&gt;Alternatively, you use make_self&amp;lt;Impl&amp;gt;, which creates the object but returns a winrt::com_ptr&amp;lt;Impl&amp;gt; instead of a projection. You can then access things in the implementation object from that winrt::com_ptr, and convert it to the projected type with the * operator.&lt;br/&gt;make&lt;br/&gt;make_self&lt;br/&gt;↓&lt;br/&gt;↓&lt;br/&gt;projection&lt;br/&gt;get_self&lt;br/&gt;→&lt;br/&gt;implementation&lt;br/&gt;←&lt;br/&gt;operator*&lt;br/&gt;Which one you choose depends on where you want to go first.&lt;br/&gt;If you are first going to access non-projected public members of the implementation class, use the -&amp;gt; operator on the com_ptr&amp;lt;Impl&amp;gt;. For example, you might want to set up the object before returning the projection.&lt;br/&gt;winrt::IVector&amp;lt;winrt::Widget&amp;gt;&lt;br/&gt;MakeWidgets(int style, int count)&lt;br/&gt;{&lt;br/&gt;std::vector&amp;lt;winrt::Widget&amp;gt; v(count, nullptr);&lt;br/&gt;std::generate(v.begin(), v.end(), [&amp;amp;] {&lt;br/&gt;auto widget = winrt::make_self&amp;lt;implementation::Widget&amp;gt;(style);&lt;br/&gt;widget-&amp;gt;Enabled(true);&lt;br/&gt;return *widget;&lt;br/&gt;});&lt;br/&gt;return winrt::multi_threaded_vector(std::move(v));&lt;br/&gt;}&lt;br/&gt;But if you are just going to use the projection, you can take the direct route instead of going the long way.&lt;br/&gt;// The long way&lt;br/&gt;winrt::IVector&amp;lt;winrt::Widget&amp;gt;&lt;br/&gt;MakeWidgets(int style, int count)&lt;br/&gt;{&lt;br/&gt;std::vector&amp;lt;winrt::Widget&amp;gt; v(count, nullptr);&lt;br/&gt;std::generate(v.begin(), v.end(), [&amp;amp;] {&lt;br/&gt;auto widget = winrt::make_self&amp;lt;implementation::Widget&amp;gt;(style);&lt;br/&gt;return *widget;&lt;br/&gt;});&lt;br/&gt;return winrt::multi_threaded_vector(std::move(v));&lt;br/&gt;}&lt;br/&gt;make_self&lt;br/&gt;↓&lt;br/&gt;projection&lt;br/&gt;←&lt;br/&gt;operator*&lt;br/&gt;implementation&lt;br/&gt;↓&lt;br/&gt;returned&lt;br/&gt;In this case, you don’t need to pass through the implementation type.&lt;br/&gt;// The short way&lt;br/&gt;winrt::IVector&amp;lt;winrt::Widget&amp;gt;&lt;br/&gt;MakeWidgets(int style, int count)&lt;br/&gt;{&lt;br/&gt;std::vector&amp;lt;winrt::Widget&amp;gt; v(count, nullptr);&lt;br/&gt;std::generate(v.begin(), v.end(), [&amp;amp;] {&lt;br/&gt;return winrt::make_self&amp;lt;implementation::Widget&amp;gt;(style);&lt;br/&gt;});&lt;br/&gt;return winrt::multi_threaded_vector(std::move(v));&lt;br/&gt;}&lt;br/&gt;make&lt;br/&gt;↓&lt;br/&gt;projection&lt;br/&gt;↓&lt;br/&gt;return&lt;br/&gt;My guess is that the people who go the long way don’t realize that there are two ways. They learned only one way and just rely on it even if there’s a shorter way.&lt;br/&gt;The post C&#43;&#43;/WinRT overcorrection: Using &amp;lt;CODE&amp;gt;make_self&amp;lt;/CODE&amp;gt; and immediately converting it to the projected interface appeared first on The Old New Thing.&lt;br/&gt;&lt;br/&gt;&lt;a href=&#34;https://devblogs.microsoft.com/oldnewthing/20261028-00/?p=112803/&#34;&gt;https://devblogs.microsoft.com/oldnewthing/20261028-00/?p=112803/&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;#winrt #windowsruntime #interface&lt;br/&gt;&lt;br/&gt;#rss #feeds #linksharing #qwibbit
    </content>
    <updated>2026-10-28T22:01:54Z</updated>
  </entry>

  <entry>
    <id>https://njump.me/nevent1qqsvxn5s3zfgx04h7m2xqr8pusdqwl43k7flfhdh8d6e24persfqcggzyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gvp3g0ge</id>
    
      <title type="html">Why don’t we run the taskbar and Task Manager at high priority, ...</title>
    
    <link rel="alternate" href="https://njump.me/nevent1qqsvxn5s3zfgx04h7m2xqr8pusdqwl43k7flfhdh8d6e24persfqcggzyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gvp3g0ge" />
    <content type="html">
      Why don’t we run the taskbar and Task Manager at high priority, so they can remain responsive?&lt;br/&gt;&lt;br/&gt;If a system becomes CPU-starved, all processes begin to suffer. This includes the taskbar and Task Manager, even though they are often the tools you want to use to stop whatever it is that’s making your system suffer. Why can’t we run the taskbar and Task Manager at high priority?&lt;br/&gt;The catch with running anything at high priority is that unless you have been very careful to avoid it, you will eventually run into a shared resource that you will have to wait for, and you are now stuck. Your priority checkout pass gets you to the front of the line, but if the person at the register has a large shopping cart full of groceries, you just have to wait until they are done before you get your chance.&lt;br/&gt;Even if the code that protects the shared resource is careful to avoid priority inversion by transferring the priority of the waiter to the thread that owns the resource, you are still stuck waiting, and that owning thread might be doing something that takes a long time, like, say, accessing a file over the network.&lt;br/&gt;For UI code, this problem is particularly acute because you will eventually have to call into the UI system, and now you’re duking it out with all the other UI threads in the system.&lt;br/&gt;The problem is that it’s hard to fix a runaway system from within that same system. The tools which you can use to try to fix the system may already have been compromised. And it’s definitely hard to fix a runaway system if your tools have to share critical resources with the thing that is out of control. Windows already gives preferential treatment to the program that is in focus, so if you can get focus onto the taskbar or Task Manager, you are doing about as well as you can. But that preferential treatment takes you only so far if those preferred threads find themselves blocked on things that are controlled by non-preferred threads.&lt;br/&gt;The post Why don’t we run the taskbar and Task Manager at high priority, so they can remain responsive? appeared first on The Old New Thing.&lt;br/&gt;&lt;br/&gt;&lt;a href=&#34;https://devblogs.microsoft.com/oldnewthing/20261027-00/?p=112800/&#34;&gt;https://devblogs.microsoft.com/oldnewthing/20261027-00/?p=112800/&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;#taskmanager #highpriority #even&lt;br/&gt;&lt;br/&gt;#rss #feeds #linksharing #qwibbit
    </content>
    <updated>2026-10-28T10:03:13Z</updated>
  </entry>

  <entry>
    <id>https://njump.me/nevent1qqswhah00rj8qndfq0ayt2ce9zw5g79tc846t0us66psdnfckce5dkqzyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gvquq4ym</id>
    
      <title type="html">Puzzling out why a program doesn’t work when run from a batch ...</title>
    
    <link rel="alternate" href="https://njump.me/nevent1qqswhah00rj8qndfq0ayt2ce9zw5g79tc846t0us66psdnfckce5dkqzyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gvquq4ym" />
    <content type="html">
      Puzzling out why a program doesn’t work when run from a batch file, but works when double-clicked from Explorer&lt;br/&gt;&lt;br/&gt;A customer asked for help writing a batch file to launch a program. For some reason, the program displayed an error message when the batch file ran it, whereas it worked fine when they double-clicked the program from Explorer.&lt;br/&gt;I immediately suspected that they were not setting the current directory.&lt;br/&gt;Some time ago, I noted that when you double-click a file in Explorer, Explorer sets the current directory of the program to the directory containing the thing that you double-clicked. This is done to accomodate programs that look for ancillary files in the current directory. The example I had was a hypothetical LitWare Writer program that, when given an ABC.LIT file, looks for related files like ABC.LTC (the table of contents) and ABC.LDC (the custom dictionary) in the current directory.&lt;br/&gt;This also happens if you double-click the .exe file: The current directory is set to the directory that contains the executable.&lt;br/&gt;My guess is that the customer’s program looks for ancillary files relative to its current directory, but the batch file ran the program by its full path without changing the current directory to match the program’s path.&lt;br/&gt;The customer confirmed that explicitly changing the directory fixed the program. (More specifically, they used pushd to change the directory and then popd to restore the original directory.)&lt;br/&gt;Bonus chatter: It didn’t come to it, but my second idea would have been to check whether the program had set a custom entry under App Paths to ask for additional directories to be added to the PATH environment variable when the program is run.&lt;br/&gt;The post Puzzling out why a program doesn’t work when run from a batch file, but works when double-clicked from Explorer appeared first on The Old New Thing.&lt;br/&gt;&lt;br/&gt;&lt;a href=&#34;https://devblogs.microsoft.com/oldnewthing/20261026-00/?p=112797/&#34;&gt;https://devblogs.microsoft.com/oldnewthing/20261026-00/?p=112797/&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;#batchfile #explorer #run #path #apppaths&lt;br/&gt;&lt;br/&gt;#rss #feeds #linksharing #qwibbit
    </content>
    <updated>2026-10-27T00:13:40Z</updated>
  </entry>

  <entry>
    <id>https://njump.me/nevent1qqsydr34ajj8zx7y6mgqc78g4xa43z42u4lzjfrljd609mfp3hj2mnczyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gvkjjwyt</id>
    
      <title type="html">Why didn’t we use Co­Register­Initialize­Spy to clean up the ...</title>
    
    <link rel="alternate" href="https://njump.me/nevent1qqsydr34ajj8zx7y6mgqc78g4xa43z42u4lzjfrljd609mfp3hj2mnczyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gvkjjwyt" />
    <content type="html">
      Why didn’t we use Co­Register­Initialize­Spy to clean up the unmarshalable delegate?&lt;br/&gt;&lt;br/&gt;Another suggestion from Luca Bacci on creating a fake agile wrapper that is technically agile but is not useful outside its home apartment was to use the IInitialize­Spy interface.&lt;br/&gt;Some of the thing that made The Ro­Register­For­Apartment­Shutdown unsuitable also apply to Co­Register­Initialize­Spy. For example, you are required to revoke the spy from the same thread that registered it, which means that we have to remember the original thread so we can somehow get back to executing code on it.&lt;br/&gt;Another problem is explicitly noted in the documentation for Co­Revoke­Initialize­Spy:&lt;br/&gt;It is unpredictable whether a call to Co­Revoke­Initialize­Spy from within an IInitialize­Spy method call will have an effect during the current top-level (non-nested) call to Co­InitializeEx or Co­Uninitialize.&lt;br/&gt;This is the same problem we had with Ro­Unregister­For­Apartment­Shutdown function, in the case where the original object’s destruction in turn triggers an attempt to revoke an initialize spy: It revokes the spy, thinking that this will stop the callbacks, but in fact, the callback might still happen.&lt;br/&gt;It also suffers from the same implementation issue regarding the number of initialize spies: Registration is O(1), but unregistration is O(n) because it does a linear search through a linked list. The assumption is that initialize spies are rarely unregistered before they are triggered.&lt;br/&gt;But there’s an even bigger problem that makes this completely unsuitable for using an initialize spy to clean up an object at apartment shutdown, and maybe you noticed it in the earlier discussion.&lt;br/&gt;Initialize spies are registered on a per-thread basis, not per-apartment.&lt;br/&gt;If the original object is in the multi-threaded apartment, then it’s wrong to give up the object once the original thread uninitializes COM, because it might still be kept alive by another thread.&lt;br/&gt;Also, a thread may change apartments over time. For example, if you are not in the neutral apartment and you call into an object that is in the neutral apartment, then there is no thread switch. COM merely removes your thread temporarily from whatever apartment it is in and puts the thread into the neutral apartment for the duration of the call.&lt;br/&gt;Now, if the thread had previously belonged to a single-threaded apartment, and somebody makes a call into an object on that single-threaded apartment, COM may temporarily remove that thread from the neutral apartment and put it back into the original single-threaded apartment for the duration of that call.&lt;br/&gt;A thread may move between apartments during its lifetime, but the IInitialize­Spy is tied to the thread, not to the apartment.&lt;br/&gt;This means that if the non-marshalable object happens to live in, say, the neutral apartment, you would be given that object in the neutral apartment, and you would register your IInitialize­Spy against the thread that is currently running. When that thread uninitializes COM as a single-threaded apartment, your Pre­Uninitialize would be running in that dying single-threaded apartment, but it can’t clean up the object because the object is in the neutral apartment, not the single-threaded apartment.&lt;br/&gt;So yeah, IInitialize­Spy doesn’t really help.&lt;br/&gt;The post Why didn’t we use &amp;lt;CODE&amp;gt;Co­Register­Initialize­Spy&amp;lt;/CODE&amp;gt; to clean up the unmarshalable delegate? appeared first on The Old New Thing.&lt;br/&gt;&lt;br/&gt;&lt;a href=&#34;https://devblogs.microsoft.com/oldnewthing/20261022-00/?p=112791/&#34;&gt;https://devblogs.microsoft.com/oldnewthing/20261022-00/?p=112791/&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;#apartment #lucabacci #initialize #clean #use #com #spy&lt;br/&gt;&lt;br/&gt;#rss #feeds #linksharing #qwibbit
    </content>
    <updated>2026-10-23T23:45:07Z</updated>
  </entry>

  <entry>
    <id>https://njump.me/nevent1qqsx57nlh3732ysl287myv6lwtu7j4792jmr0ez7zppeqzslq8r54hszyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gvdjqey7</id>
    
      <title type="html">Why didn’t we use the COM static store to clean up the ...</title>
    
    <link rel="alternate" href="https://njump.me/nevent1qqsx57nlh3732ysl287myv6lwtu7j4792jmr0ez7zppeqzslq8r54hszyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gvdjqey7" />
    <content type="html">
      Why didn’t we use the COM static store to clean up the unmarshalable delegate?&lt;br/&gt;&lt;br/&gt;A third suggestion from Luca Bacci on creating a fake agile wrapper that is technically agile but is not useful outside its home apartment was to use the COM static store.&lt;br/&gt;The COM static store doesn’t help us, because the COM static store runs down when the last thread shuts down COM, whereas we want something that runs down when a single apartment shuts down COM.&lt;br/&gt;There is a per-apartment version of the COM static store, but it is part of the Core­Application­View, which is (1) something that only UWP programs have, and (2) exists only for apartments that have a core application view, and those are restricted to single-threaded apartments.&lt;br/&gt;Even if there were a per-apartment static store, putting something into it would require generating a unique name and remembering it for later removal. You could probably use the stringified address of the object, with a fixed GUID prefix as a pseudo-namespace. Since we’re dealing with a dictionary, the insertion and removal operations are going to be O(log n) or O(1), depending on the implementation, but even the constant-time version will have a higher constant than a single index lookup in the Global Interface Table.&lt;br/&gt;The post Why didn’t we use the COM static store to clean up the unmarshalable delegate? appeared first on The Old New Thing.&lt;br/&gt;&lt;br/&gt;&lt;a href=&#34;https://devblogs.microsoft.com/oldnewthing/20261023-00/?p=112793/&#34;&gt;https://devblogs.microsoft.com/oldnewthing/20261023-00/?p=112793/&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;#comstatic #staticstore #lucabacci #interfacetable #globalinterface&lt;br/&gt;&lt;br/&gt;#rss #feeds #linksharing #qwibbit
    </content>
    <updated>2026-10-23T23:10:56Z</updated>
  </entry>

  <entry>
    <id>https://njump.me/nevent1qqst32my0fcnjy4fmr88xajkahh572fgjkztaxhp6aemfcyqx7g5jeszyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gv0dzsht</id>
    
      <title type="html">Microspeak: Drain the slide, back-up slides Recall that ...</title>
    
    <link rel="alternate" href="https://njump.me/nevent1qqst32my0fcnjy4fmr88xajkahh572fgjkztaxhp6aemfcyqx7g5jeszyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gv0dzsht" />
    <content type="html">
      Microspeak: Drain the slide, back-up slides&lt;br/&gt;&lt;br/&gt;Recall that Microspeak is not merely for jargon exclusive to Microsoft, but it’s jargon that you need to know to survive at Microsoft. Even if you don’t use it yourself, you need to know what it means when others say it.&lt;br/&gt;To drain the slide is, as Mark Myers explains it, reading the contents of a slide to the audience when giving a presentation. At least at Microsoft, the term is frequently used by a speaker in the negative, such as “I don’t want to drain the slide here…”&lt;br/&gt;My theory is that the phenomenon of draining the slide has multiple sources.&lt;br/&gt;One is simply the result of inexperience on the part of the presenter. They don’t know what to say when giving a presentation, so they end up just reading out the text that they wrote on the slide.&lt;br/&gt;A more insidious source is the result of tension between the multiple reason for creating a slide deck.&lt;br/&gt;One reason to create a slide deck is to accompany a presentation. The focus of the presentation is the speaker, and the slide deck is there merely as a visual aid.&lt;br/&gt;Another reason to create a slide deck is to provide a lasting record of the presentation and to serve as a reference for the future. If the topic is “How to perform process X”, then you want to make sure that all of the necessary steps are spelled out on the slides, so that you can share a link to the slide deck in the invitation for others to refer to both during the presentation but mostly for reference afterwards. People will refer back to the slides the next time they need to do process X, and they probably don’t want to have to scrub through a one-hour recording just to extract the five steps they need to follow.&lt;br/&gt;Yet another reason for creating a slide deck is when presenting to a senior executive, such as for use in a placemat review. There is probably a standard template for the meeting, such as an “Accomplishments since the last meeting”, perhaps broken into “What’s going well”, “What’s not going well”, and followed by an “Items of future concern”. The meeting may run into a time crunch (because they always run over), and you may not get enough time to get through all your slides, so you want to be able to say, “You can read the rest of the slides after the meeting.” (An extreme case of this is where other teams in the placemat meeting run long and leave you with no time at all!)&lt;br/&gt;A related reason for creating a slide deck is as a “proof of work”. Going into the placement review, you don’t have much to report, but you have to fill the slide. If you don’t, it looks like you haven’t done anything.&lt;br/&gt;I was reminded of this last reason when I worked with a colleague to prepare our team’s weekly placemat report. My colleague would fill the slide with information, and I would recommend replacing most of the bullet points with a much more succicient summary, or just removing the items outright.&lt;br/&gt;Partner Team X is considering the possibility of deploying a version that uses widgets before all of the widget features are fully implemented and rolled out to customers. They understand the consequences, such as impaired reverse widget flow. Some of these missing features will light up when the implementation is ready, but others will be stuck in a broken state unless explicit remediations are performed after the implementation rolls out, and a small number of features will be irreparably broken, with the only recourse being to destroy all the affected widgets and recreate them. Partner Team X has been advised of the various failure modes and how they can recover from the ones that are recoverable, and they are assessing whether they want to proceed with early deployment.&lt;br/&gt;I simplified it to&lt;br/&gt;Partner Team X understands the consequences of and limited recovery from using widgets in production before our work is fully implemented and deployed.&lt;br/&gt;The people who are receiving this slide deck are not interested in the fine details. They want the 25-word summary of how things are going so that they can either decide that our feature is not a point of concern, or decide to ask follow-up questions to understand the issue better. In that case, we can present a so-called back-up slide with the details.&lt;br/&gt;A back-up slide is a slide in a slide deck that you hope that you won’t need to use, but which you create just in case it is needed. You mark it as hidden or put it in an appendix so that it doesn’t show up in the normal presentation flow. But if the audience you are presenting to (usually someone higher up the executive chain) asks a follow-up question about one of your slides, you can reach into your deck and pull out your back-up slide to answer it. “I was ready for that question, so I already have a slide with the data you are asking for.”&lt;br/&gt;Bonus PowerPoint jargon: PowerPoint Karaoke and the eye chart.&lt;br/&gt;The post Microspeak: Drain the slide, back-up slides appeared first on The Old New Thing.&lt;br/&gt;&lt;br/&gt;&lt;a href=&#34;https://devblogs.microsoft.com/oldnewthing/20261020-00/?p=112784/&#34;&gt;https://devblogs.microsoft.com/oldnewthing/20261020-00/?p=112784/&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;#slide #microsoft #microspeak #markmyers&lt;br/&gt;&lt;br/&gt;#rss #feeds #linksharing #qwibbit
    </content>
    <updated>2026-10-22T01:45:50Z</updated>
  </entry>

  <entry>
    <id>https://njump.me/nevent1qqswsz3gj38tx9c5qnv8lq7ap0f7pqrwdd37l448tmx2hnxz0nznhwczyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gvekacca</id>
    
      <title type="html">Why didn’t we use Ro­Register­For­Apartment­Shutdown to ...</title>
    
    <link rel="alternate" href="https://njump.me/nevent1qqswsz3gj38tx9c5qnv8lq7ap0f7pqrwdd37l448tmx2hnxz0nznhwczyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gvekacca" />
    <content type="html">
      Why didn’t we use Ro­Register­For­Apartment­Shutdown to clean up the unmarshalable delegate?&lt;br/&gt;&lt;br/&gt;In my attempt to create a fake agile wrapper that is technically agile but is not useful outside its home apartment, Luca Bacci suggested, among other things, using the Ro­Register­For­Apartment­Shutdown function.&lt;br/&gt;The Ro­Register­For­Apartment­Shutdown function is nice, but it doesn’t suit our needs.&lt;br/&gt;One problem is that the object registered for apartment shutdown must be agile. (If you pass a non-agile object, the call fails.) That means that our wrapper must be agile. If we put the non-marshalable non-agile object inside our wrapper, we now have an agile object (the wrapper) that holds a non-agile object (the original object) as a member, which creates the risk that the wrapper will run down in the wrong apartment. The normal way of fixing that is to use Ro­Get­Agile­Reference to create an agile wrapper around the non-agile object, and store that agile wrapper in our container object.&lt;br/&gt;This puts us back where we started: We are trying to implement that agile wrapper!&lt;br/&gt;Even if we got past that problem, we have another problem: At apartment shutdown, COM calls the wrapper object’s UnInitialize method, and there’s a warning on the using the Ro­Unregister­For­Apartment­Shutdown function:&lt;br/&gt;Warning: Don’t call the Ro­Unregister­For­Apartment­Shutdown function from the OnUninitialize callback.&lt;br/&gt;But wait, what if the destructor of the object we are wrapping wants to call Ro­Unregister­For­Apartment­Shutdown? It might happen indirectly because it has its own reference to another object, that in turn tries to call Ro­Unregister­For­Apartment­Shutdown.&lt;br/&gt;For example, it might hold another fake agile wrapper whose UnInitialize method has already been called! (We can work around that in our agile wrapper by nulling out the non-agile pointer so we don’t double-release, but maybe there’s some other object that uses Ro­Unregister­For­Apartment­Shutdown that is less resilient to this scenario.)&lt;br/&gt;Another requirement of Ro­Unregister­For­Apartment­Shutdown is that it must be called from the same apartment that registered. This doesn’t quite put us back where we started, but it makes things more complicated because the whole point of the exercise is to find a way to release the object without having to try to switch to the apartment. I guess what we could do is use IContext­Callback to try to switch back to the apartment to release the original object and unregister the apartment shutdown callback. If the apartment switch fails, then we assume it’s because the apartment has already run down, so we assume that the IApartment­Shutdown::On­Uninitialize method was called, and it released the object for us. (Of course, that still creates the problem that we are cleaning up inside the On­Uninitialize callback, which meas that nobody else can unregister their apartment shutdown callback.)&lt;br/&gt;The last note on this is that the implementation is written on the assumption that there are not a lot of apartment shutdown callbacks. Registration is O(1), but unregistration is O(n) because it does a linear search through all of the apartment’s registered shutdown callbacks to find the one being unregistered. By comparison, the Global Interface Table is designed on the assumption that it will have to manage a lot of objects, so it can look up its cookies in O(1) time. The proposed alternate design would register and unregister a lot of apartment shutdown callbacks, so it’s pushing the apartment shutdown callback list into a usage pattern it wasn’t optimized for.&lt;br/&gt;The post Why didn’t we use &amp;lt;CODE&amp;gt;Ro­Register­For­Apartment­Shutdown&amp;lt;/CODE&amp;gt; to clean up the unmarshalable delegate? appeared first on The Old New Thing.&lt;br/&gt;&lt;br/&gt;&lt;a href=&#34;https://devblogs.microsoft.com/oldnewthing/20261021-00/?p=112786/&#34;&gt;https://devblogs.microsoft.com/oldnewthing/20261021-00/?p=112786/&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;#agile #apartment #lucabacci #use #shutdown #another&lt;br/&gt;&lt;br/&gt;#rss #feeds #linksharing #qwibbit
    </content>
    <updated>2026-10-22T01:20:58Z</updated>
  </entry>

  <entry>
    <id>https://njump.me/nevent1qqsg8lgw2e09exlk4nyg72aclgf6td247p9s6ndays05zlyvs23ap3czyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gvgk4jaq</id>
    
      <title type="html">Why do we need ud2 when int 6 is right there? Some time ago, I ...</title>
    
    <link rel="alternate" href="https://njump.me/nevent1qqsg8lgw2e09exlk4nyg72aclgf6td247p9s6ndays05zlyvs23ap3czyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gvgk4jaq" />
    <content type="html">
      Why do we need ud2 when int 6 is right there?&lt;br/&gt;&lt;br/&gt;Some time ago, I mentioned that the ud2 instruction was created to be an architecturally undefined instruction. But why not just use an int 6 instruction? It’s a two-byte instruction, just like ud2, and interrupt vector 6 is the invalid opcode vector, so a program could just invoke it manually and get whatever behavior the operating system assigns to an attempt to execute an invalid opcode.&lt;br/&gt;Well, not exactly.&lt;br/&gt;Architecturally, the invalid opcode is a fault, which means that the address of the faulting instruction is reported to the exception handler. On the other hand, the int 6 is a trap, which means that the address of the instruction after the int 6 is reported to the handler.&lt;br/&gt;This distinction between faults and traps reflects how they are used. A fault represents an error that the kernel could attempt to repair and retry. For example, a page fault could be repaired by paging the memory in. An access violation could be repaired by changing the page protections. A trap reports an operation that has already occurred and gives you a chance to do some special work in response to it before resuming execution. In the case of a software interrupt, the handler wants to process whatever the interrupt means, and then resume execution with the next instruction.&lt;br/&gt;Now, some faults are unlikely to be repaired, but reporting them as faults means that you have to take extra steps if you want to execute past them. If you just ignore the fault, the instruction restarts and faults again.&lt;br/&gt;If you manually raise the int 6 interrupt to simulate a #UD undefined instruction fault, the handler will think it’s dealing with a CPU-generated undefined instruction fault, so it expects the instruction pointer in the fault frame to point to the undefined instruction. But since int puts the address of the next instruction into the fault frame, the fault handler will look at the instruction and get confused as to why the invalid instruction fault was raised. “It says here that the faulting instruction is a xor eax, eax. That’s a perfectly legitimate instruction. Why did it fault?”&lt;br/&gt;One case for inspecting the faulting instruction is to emulate missing instructions on older processors.&lt;br/&gt;Furthermore, in protected mode, you need to have permission to issue an int 6. The interrupt descriptor table describes what to do for each interrupt, as well as what CPU privilege level is permitted to invoke it explicitly. And to avoid exactly these types of problems where a user-mode program issues an int 6 and confuses the #UD handler, all operating systems deny int 6 privileges to user mode.&lt;br/&gt;So even if you try to fake a #UD via an explicit int 6, it doesn’t work. To get the #UD undefined instruction fault, you have to issue an actual undefined instruction.&lt;br/&gt;The post Why do we need &amp;lt;CODE&amp;gt;ud2&amp;lt;/CODE&amp;gt; when &amp;lt;CODE&amp;gt;int 6&amp;lt;/CODE&amp;gt; is right there? appeared first on The Old New Thing.&lt;br/&gt;&lt;br/&gt;&lt;a href=&#34;https://devblogs.microsoft.com/oldnewthing/20261019-00/?p=112781/&#34;&gt;https://devblogs.microsoft.com/oldnewthing/20261019-00/?p=112781/&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;#rss #feeds #linksharing #qwibbit
    </content>
    <updated>2026-10-20T14:21:44Z</updated>
  </entry>

  <entry>
    <id>https://njump.me/nevent1qqsglyq425wnhj7x8tuhuspsfzrp3z78d0jxzt2sdy02tl2gkykj8vszyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gvhw6k6c</id>
    
      <title type="html">C&#43;&#43; futures part 5: std::future and std::shared_future Wrapping ...</title>
    
    <link rel="alternate" href="https://njump.me/nevent1qqsglyq425wnhj7x8tuhuspsfzrp3z78d0jxzt2sdy02tl2gkykj8vszyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gvhw6k6c" />
    <content type="html">
      C&#43;&#43; futures part 5: std::future and std::shared_future&lt;br/&gt;&lt;br/&gt;Wrapping up our quick introduction to the C&#43;&#43; futures library, we come to the last two parts: std::future and std::shared_future.&lt;br/&gt;The std::future is the starting point. It is a move-only class that this takes the source and forwards its wait and wait_for methods to the source, and forwards its get method to consume.&lt;br/&gt;Forwarding the get to consume means that you can call get only once.&lt;br/&gt;The idea is that std::future is for the case where there is exactly one consumer of the value. Since it is move-only, you can’t copy it; you can only give it away and transfer the power to retrieve the value to the recipient.&lt;br/&gt;The std::future has a method called shared(). This transfers the source from the future to a shared_future object. The shared_future also forwards its wait and wait_for methods to the source, but instead of forwarding its get to the source::consume, shared_future::get() just calls source::get to get a reference to the value storage.&lt;br/&gt;This is what makes the “shared future” shared: The shared_future is copyable, so you can have multiple people all with their own shared_future that share the same source, and each one can separately wait for the value and retrieve the value as many times as they want.&lt;br/&gt;The downside of shared_future is that you always get a const reference, so if you want to perform non-const operations on the result, you’ll have to make a copy and operate on the copy. And that’s not possible at all if the result is itself a move-only type, since you can’t move out of a const reference.&lt;br/&gt;You can see that at the end of the day, all of the pieces of the futures library are just different ways of manipulating the invisible source. Some components push values into the source, and others pull values out of the source.&lt;br/&gt;It took me a while to realize that the most important part of the whole futures library is something you can’t even see.&lt;br/&gt;Bonus chatter: All the names in the futures library are horrible. I mean, really, “packaged task”?&lt;br/&gt;Here’s my attempt to give the pieces better names:&lt;br/&gt;Old name&lt;br/&gt;New name&lt;br/&gt;promise&lt;br/&gt;promise_source&lt;br/&gt;packaged_task&lt;br/&gt;function_promise_source&lt;br/&gt;async(deferred)&lt;br/&gt;make_lazy_promise&lt;br/&gt;async(async)&lt;br/&gt;make_thread_promise&lt;br/&gt;future&lt;br/&gt;promise&lt;br/&gt;shared_future&lt;br/&gt;shared_promise&lt;br/&gt;I admit, these names aren’t all that good either. But I prefer to use the word “promise” to refer to the thing that “promises” to produce a value. And the pattern promise_source / promise makes the relationship between the two much clearer: A promise source is a thing that makes promises. And it avoids the hilarity of a non-async async().&lt;br/&gt;The post C&#43;&#43; futures part 5: &amp;lt;CODE&amp;gt;std::&amp;lt;WBR&amp;gt;future&amp;lt;/CODE&amp;gt; and &amp;lt;CODE&amp;gt;std::&amp;lt;WBR&amp;gt;shared_future&amp;lt;/CODE&amp;gt; appeared first on The Old New Thing.&lt;br/&gt;&lt;br/&gt;&lt;a href=&#34;https://devblogs.microsoft.com/oldnewthing/20261016-00/?p=112778/&#34;&gt;https://devblogs.microsoft.com/oldnewthing/20261016-00/?p=112778/&lt;/a&gt;
    </content>
    <updated>2026-10-16T15:12:18Z</updated>
  </entry>

  <entry>
    <id>https://njump.me/nevent1qqsr20aar546cvmtcgdlx45mw4vz30w03zr2rnuhv35ad6ea4e9wwcqzyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gvxdy5je</id>
    
      <title type="html">One way of thinking about access specifiers in C&#43;&#43;/WinRT ...</title>
    
    <link rel="alternate" href="https://njump.me/nevent1qqsr20aar546cvmtcgdlx45mw4vz30w03zr2rnuhv35ad6ea4e9wwcqzyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gvxdy5je" />
    <content type="html">
      One way of thinking about access specifiers in C&#43;&#43;/WinRT implementation types&lt;br/&gt;&lt;br/&gt;In C&#43;&#43;/WinRT, Windows Runtime classes are exposed to the outside world through the projection, but internally they are represented by their implementation type. Since the outside world sees only the projection, implementation types are visible only to the module that produced them.&lt;br/&gt;This realization lets you reinterpret the C&#43;&#43; access specifiers for C&#43;&#43;/WinRT implementation types.&lt;br/&gt;Declared on&lt;br/&gt;implementation as&lt;br/&gt;C# and C&#43;&#43;/CX&lt;br/&gt;equivalent&lt;br/&gt;Accessible to&lt;br/&gt;implemented interface&lt;br/&gt;public&lt;br/&gt;Anyone&lt;br/&gt;public&lt;br/&gt;internal&lt;br/&gt;Code in the same module&lt;br/&gt;protected&lt;br/&gt;protected&lt;br/&gt;Code in derived classes&lt;br/&gt;private&lt;br/&gt;private&lt;br/&gt;Code in the same class&lt;br/&gt;In code:&lt;br/&gt;struct Widget : winrt::implements&amp;lt;Widget, IStringable&amp;gt;&lt;br/&gt;{&lt;br/&gt;public:&lt;br/&gt;// This is a member of IStringable,&lt;br/&gt;// so it is accessible to anyone.&lt;br/&gt;winrt::hstring ToString();&lt;br/&gt;// This does not implement any member from IStringable,&lt;br/&gt;// so it is accessible to other code in the same module.&lt;br/&gt;void Recolor(winrt::Windows::UI::Color newColor);&lt;br/&gt;protected:&lt;br/&gt;// Accessible to implementation classes that derive from Widget.&lt;br/&gt;void Reverse();&lt;br/&gt;private:&lt;br/&gt;// Accessible only to Widget itself.&lt;br/&gt;void Reset();&lt;br/&gt;};&lt;br/&gt;Note that if you are implementing a runtime class, then C&#43;&#43;/WinRT autogenerates a template for you that auto-declares all of the declared interfaces of that class.&lt;br/&gt;// Widget.idl&lt;br/&gt;namespace Contoso&lt;br/&gt;{&lt;br/&gt;runtimeclass Widget : Windows.Foundation.IStringable&lt;br/&gt;{&lt;br/&gt;String Name{ get; };&lt;br/&gt;void Toggle();&lt;br/&gt;}&lt;br/&gt;}&lt;br/&gt;The IDL compiler autogenerates an interface IWidget with a property Name and a method Toggle().&lt;br/&gt;// implementation&lt;br/&gt;namespace winrt::Contoso&lt;br/&gt;{&lt;br/&gt;struct Widget : WidgetT&amp;lt;Widget&amp;gt;&lt;br/&gt;{&lt;br/&gt;⟦ ... ⟧&lt;br/&gt;};&lt;br/&gt;}&lt;br/&gt;The WidgetT&amp;lt;Widget&amp;gt; expands to implements&amp;lt;Widget, IWidget, Windows::Foundation::IStringable&amp;gt; because those are the interfaces declared by the IDL file.&lt;br/&gt;The post One way of thinking about access specifiers in C&#43;&#43;/WinRT implementation types appeared first on The Old New Thing.&lt;br/&gt;&lt;br/&gt;&lt;a href=&#34;https://devblogs.microsoft.com/oldnewthing/20261009-00/?p=112764/&#34;&gt;https://devblogs.microsoft.com/oldnewthing/20261009-00/?p=112764/&lt;/a&gt;
    </content>
    <updated>2026-10-16T07:33:38Z</updated>
  </entry>

  <entry>
    <id>https://njump.me/nevent1qqs2q5aqns90rp3qu5mh9k432m85wrnf2nhhnwnxqytlx583arhpanqzyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gvkud0gk</id>
    
      <title type="html">C&#43;&#43; futures part 1: The mental model The C&#43;&#43; standard library has ...</title>
    
    <link rel="alternate" href="https://njump.me/nevent1qqs2q5aqns90rp3qu5mh9k432m85wrnf2nhhnwnxqytlx583arhpanqzyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gvkud0gk" />
    <content type="html">
      C&#43;&#43; futures part 1: The mental model&lt;br/&gt;&lt;br/&gt;The C&#43;&#43; standard library has a group of related functions and classes: std::promise, std::packaged_task, std::async, std::future, and std::sharedfuture.&lt;br/&gt;The idea is that all of these classes are built of a single unnamed class which the C&#43;&#43; standard library calls the “state”, but for the purpose of discussion, I’m going to call it the source, since it is the thing that produces the value, and it behaves analogously to a C# task completion source.&lt;br/&gt;The source conceptually supports these operations:&lt;br/&gt;Set a value.&lt;br/&gt;Set an exception.&lt;br/&gt;Wait for a value or exception to be set.&lt;br/&gt;Retrieve the value or rethrow the exception.&lt;br/&gt;Here’s a simplified version that doesn’t support references.&lt;br/&gt;template&amp;lt;typename T&amp;gt;&lt;br/&gt;struct source&lt;br/&gt;{&lt;br/&gt;private:&lt;br/&gt;enum what {&lt;br/&gt;nothing,&lt;br/&gt;value,&lt;br/&gt;exception,&lt;br/&gt;consumed,&lt;br/&gt;} d; // discriminant&lt;br/&gt;union {&lt;br/&gt;T value;&lt;br/&gt;std::exception_ptr ex;&lt;br/&gt;} r; // result&lt;br/&gt;std::mutex m;&lt;br/&gt;std::condition_variable cv;&lt;br/&gt;The discriminant tells us what is in the union: Nothing (because nobody has set anything), a value, an exception, or nothing (because the value has been consumed).&lt;br/&gt;The mutex ensures thread-safe access to the other members, and the condition variable lets us wait for somebody to set a value or exception.&lt;br/&gt;void must_be_empty() {&lt;br/&gt;if (d != what::empty) {&lt;br/&gt;throw std::future_error(future_errc::promise_already_satisfied);&lt;br/&gt;}&lt;br/&gt;}&lt;br/&gt;You can call the set methods only when the source is empty, so we’ll factor out the emptiness check.&lt;br/&gt;public:&lt;br/&gt;void set_value(T&amp;amp; v) {&lt;br/&gt;std::lock_guard g(m);&lt;br/&gt;must_be_empty();&lt;br/&gt;new(&amp;amp;r.value) T(v); // &amp;#34;r.value = v&amp;#34;&lt;br/&gt;d = what::value;&lt;br/&gt;cv.notify_all();&lt;br/&gt;}&lt;br/&gt;You can set a value or exception only once, so if there is already a value or exception, we yell at you. Otherwise, we save the value and notify anybody who was waiting for a value to be set.&lt;br/&gt;I won’t bother with the overload that takes T&amp;amp;&amp;amp;; it’s the same thing, but with a std::move().&lt;br/&gt;There is also a set_value_at_thread_exit which will be another topic for another day.&lt;br/&gt;Instead of setting a value, you can set an exception:&lt;br/&gt;void set_exception(std::exception_ptr ex) {&lt;br/&gt;std::lock_guard g(m);&lt;br/&gt;must_be_empty();&lt;br/&gt;new(&amp;amp;r.ex) std::exception_ptr(ex); // &amp;#34;r.ex = ex&amp;#34;&lt;br/&gt;d = what::exception;&lt;br/&gt;cv.notify_all();&lt;br/&gt;}&lt;br/&gt;It’s basically the same as set_value except that we store an exception.&lt;br/&gt;That’s how values an exceptions go into the source. The next part is waiting for the source to become nonempty.&lt;br/&gt;void wait() {&lt;br/&gt;std::lock_guard g(m);&lt;br/&gt;while (d == what::empty) {&lt;br/&gt;cv.wait(g);&lt;br/&gt;}&lt;br/&gt;}&lt;br/&gt;void wait_for(duration dur) {&lt;br/&gt;std::lock_guard g(m);&lt;br/&gt;cv.wait_for(g, dur, [&amp;amp;] { return d != what::empty; });&lt;br/&gt;}&lt;br/&gt;You can either wait indefinitely or wait for a particular duration. The wait_for method is why we have a condition variable at all. If it weren’t for that guy, we could have used std::atomic‘s wait and notify_all methods.&lt;br/&gt;The last part is getting the values out.&lt;br/&gt;void can_get() {&lt;br/&gt;if (d == what::consumed) {&lt;br/&gt;throw std::future_error(future_errc::future_already_retrieved);&lt;br/&gt;}&lt;br/&gt;if (d == what::exception) {&lt;br/&gt;std::rethrow_exception(r.ex);&lt;br/&gt;}&lt;br/&gt;}&lt;br/&gt;Regardless of how we intend to retrieve the value, it’s not legal to retrieve a value that has already been consumed. Also, if the result is an exception, we rethrow the exception.&lt;br/&gt;T consume() {&lt;br/&gt;wait();&lt;br/&gt;std::lock_guard g(m);&lt;br/&gt;can_get();&lt;br/&gt;d = what::consumed;&lt;br/&gt;return std::move(r.v);&lt;br/&gt;}&lt;br/&gt;const T&amp;amp; get() {&lt;br/&gt;wait();&lt;br/&gt;std::lock_guard g(m);&lt;br/&gt;can_get();&lt;br/&gt;return r.v;&lt;br/&gt;}&lt;br/&gt;};&lt;br/&gt;You can get the value, which returns a const reference to the underlying storage. Or you can consume the value, which moves the value out of the underlying storage and marks the value as consumed so nobody can consume or get it (because it’s not there any more).&lt;br/&gt;We can now build our other objects and functions out of this guy. We’ll do that next time.&lt;br/&gt;Bonus chatter: Writing the destructor is left as an exercise for the reader. It’s not hard, but it’s annoying because of the union.&lt;br/&gt;Bonus bonus chatter: I’m writing the series because I always forget how it works, but writing it down helps me remember.&lt;br/&gt;The post C&#43;&#43; futures part 1: The mental model appeared first on The Old New Thing.&lt;br/&gt;&lt;br/&gt;&lt;a href=&#34;https://devblogs.microsoft.com/oldnewthing/20261012-00/?p=112767/&#34;&gt;https://devblogs.microsoft.com/oldnewthing/20261012-00/?p=112767/&lt;/a&gt;
    </content>
    <updated>2026-10-16T06:04:15Z</updated>
  </entry>

  <entry>
    <id>https://njump.me/nevent1qqs09atfduh3davarchllq3gj2zxcsljd2xhf5xyat3nhfuqgp0etkqzyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gvyqj6v2</id>
    
      <title type="html">C&#43;&#43; futures part 2: The mental model for std::promise, ...</title>
    
    <link rel="alternate" href="https://njump.me/nevent1qqs09atfduh3davarchllq3gj2zxcsljd2xhf5xyat3nhfuqgp0etkqzyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gvyqj6v2" />
    <content type="html">
      C&#43;&#43; futures part 2: The mental model for std::promise, std::packaged_task&lt;br/&gt;&lt;br/&gt;Last time, we looked at the “state” that powers the std::promise, std::packaged_task, std::async, std::future, and std::sharedfuture classes. Now we’ll see how that “state” (which I call the source) gets used and passed around.&lt;br/&gt;The lifetime of the source is managed by a std::shared_ptr&amp;lt;source&amp;lt;T&amp;gt;&amp;gt;. Everybody who has a reference to the source uses this shared pointer.&lt;br/&gt;The simplest case is std::promise. The operations on std::promise pretty much map directly to the operations on the source we laid out last time.&lt;br/&gt;The next more complicated case is the std::packaged_task. This takes a callable and saves it for later. You can then call get_future to get a future and hand it to somebody as an IOU for “A value will appear here someday.”&lt;br/&gt;When you want to produce a value, you invoke the packaged_task with whatever parameters you want to pass to the original callable. The result of the invocation (either a value or an exception) is then stored in the source object, which can then be retrieved by the future.&lt;br/&gt;You can imagine a packaged task as just wrapping a promise:&lt;br/&gt;template&amp;lt;typename R, typename... Args&amp;gt;&lt;br/&gt;class packaged_task&lt;br/&gt;{&lt;br/&gt;std::promise&amp;lt;R&amp;gt; p;&lt;br/&gt;std::function&amp;lt;R(Args...)&amp;gt; func;&lt;br/&gt;public:&lt;br/&gt;template&amp;lt;typename F&amp;gt;&lt;br/&gt;packaged_task(F&amp;amp;&amp;amp; f) : func(std::forward&amp;lt;F&amp;gt;(f)) {}&lt;br/&gt;auto get_future() { return p.get_future(); }&lt;br/&gt;void operator()(Args... args) {&lt;br/&gt;try {&lt;br/&gt;p.set_value(func(args...));&lt;br/&gt;} catch (...) {&lt;br/&gt;p.set_exception(std::current_exception());&lt;br/&gt;}&lt;br/&gt;}&lt;br/&gt;};&lt;br/&gt;When you invoke it, it calls the stored callable with the arguments and puts the result in the promise.&lt;br/&gt;Okay, those were the easy cases of pushing values into the source. Next time, we’ll look at the messy case: std::async.&lt;br/&gt;The post C&#43;&#43; futures part 2: The mental model for &amp;lt;CODE&amp;gt;std::promise&amp;lt;/CODE&amp;gt;, &amp;lt;CODE&amp;gt;std::packaged_task&amp;lt;/CODE&amp;gt; appeared first on The Old New Thing.&lt;br/&gt;&lt;br/&gt;&lt;a href=&#34;https://devblogs.microsoft.com/oldnewthing/20261013-00/?p=112769/&#34;&gt;https://devblogs.microsoft.com/oldnewthing/20261013-00/?p=112769/&lt;/a&gt;
    </content>
    <updated>2026-10-16T05:20:56Z</updated>
  </entry>

  <entry>
    <id>https://njump.me/nevent1qqsvtnamd3u0n0f5pc8fnq2x5hk5g6f03uu0uvzfzxtuah5aqku56yqzyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gvl27tk0</id>
    
      <title type="html">C&#43;&#43; futures part 3: The mental model for std::async We continue ...</title>
    
    <link rel="alternate" href="https://njump.me/nevent1qqsvtnamd3u0n0f5pc8fnq2x5hk5g6f03uu0uvzfzxtuah5aqku56yqzyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gvl27tk0" />
    <content type="html">
      C&#43;&#43; futures part 3: The mental model for std::async&lt;br/&gt;&lt;br/&gt;We continue our study of C&#43;&#43; futures with std::async.&lt;br/&gt;The more complex case is the std::async. You give std::async a callable and optional parameters to pass to that callable, and you also specify how and when you want the callable to be invoked. You get two axes: Do you want it to be calculated immediately or on demand? Do you want the calculation to happen on the thread that requests the value or on its own thread?&lt;br/&gt;Now, you’d think you could fill out the table like this:&lt;br/&gt;Immediate&lt;br/&gt;On demand (“deferred”)&lt;br/&gt;Same thread&lt;br/&gt;Call now and save the value&lt;br/&gt;Call when waited&lt;br/&gt;New thread (“async”)&lt;br/&gt;Start the thread now&lt;br/&gt;Start the thread when waited&lt;br/&gt;However, that’s not what the C&#43;&#43; standard says.&lt;br/&gt;The C&#43;&#43; standard disallows asking for an immediate value on the same thread. There’s really no value to doing it that way, since there is no actual “future”; it all happens in the present! “This future could have been a function call.”&lt;br/&gt;auto f = std::async({}, calculator);&lt;br/&gt;auto result = f.get();&lt;br/&gt;This would, in theory, mean “Immediately call the calculator and wait for it to produce a value. Store it in the source and return a future that fetches the value from that source.” But that’s the same as just&lt;br/&gt;auto result = calculator();&lt;br/&gt;I’m guessing that the C&#43;&#43; standard disallows it because there’s no point.&lt;br/&gt;The C&#43;&#43; standard also says that if you combine both std::launch::deferred and std::launch::async, it doesn’t mean that you get a calculation that lazy-starts on its own thread. Instead, the standard says that the implementation can choose which flag to honor and which to ignore.&lt;br/&gt;So really, the table is&lt;br/&gt;Immediate&lt;br/&gt;On demand (“deferred”)&lt;br/&gt;Same thread&lt;br/&gt;Illegal&lt;br/&gt;Call when waited&lt;br/&gt;New thread (“async”)&lt;br/&gt;Start the thread now&lt;br/&gt;Dealer’s choice&lt;br/&gt;In all cases, the result of the callable (either a value or an exception) is stored in the source.&lt;br/&gt;Now, I noted that there’s no point to asking std::async for an immediate on-thread calculation. But maybe you want to do it anyway because you are interfacing with some other component that expects to receive a future. How could you get the same result?&lt;br/&gt;We’ll look at that next time.&lt;br/&gt;The post C&#43;&#43; futures part 3: The mental model for &amp;lt;CODE&amp;gt;std::async&amp;lt;/CODE&amp;gt; appeared first on The Old New Thing.&lt;br/&gt;&lt;br/&gt;&lt;a href=&#34;https://devblogs.microsoft.com/oldnewthing/20261014-00/?p=112774/&#34;&gt;https://devblogs.microsoft.com/oldnewthing/20261014-00/?p=112774/&lt;/a&gt;
    </content>
    <updated>2026-10-16T04:37:55Z</updated>
  </entry>

  <entry>
    <id>https://njump.me/nevent1qqsrtvsydg20eazeatm8zuzsexcewqe6tas3nzlw7zwzqgaegr3trhczyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gvgmwwa2</id>
    
      <title type="html">C&#43;&#43; futures part 4: What if I want an immediate on-thread ...</title>
    
    <link rel="alternate" href="https://njump.me/nevent1qqsrtvsydg20eazeatm8zuzsexcewqe6tas3nzlw7zwzqgaegr3trhczyr7lgfq0ym3vrqydg3yrljzhtal9rh4479yxskmfkuaml4yumw0gvgmwwa2" />
    <content type="html">
      C&#43;&#43; futures part 4: What if I want an immediate on-thread std::async?&lt;br/&gt;&lt;br/&gt;I noted last time that you are not allowed to ask std::async for an immediate on-thread calculation. The C&#43;&#43; library designers probably chose not to support it because there’s no point: An immediate on-thread calculation is just a function call, so call the function already and leave me out of it.&lt;br/&gt;But maybe you want to do it because you are interfacing with a component that wants a std::future. How could you do it?&lt;br/&gt;One way would be to implement the immediately synchronous case manually by setting a value into a promise.&lt;br/&gt;template&amp;lt;typename F, typename... Args&amp;gt;&lt;br/&gt;auto&lt;br/&gt;make_immediate_future(F&amp;amp;&amp;amp; f, Args&amp;amp;&amp;amp;... args)&lt;br/&gt;-&amp;gt; std::future&amp;lt;&lt;br/&gt;std::invoke_result_t&amp;lt;std::decay_t&amp;lt;F&amp;gt;,&lt;br/&gt;std::decay_t&amp;lt;Args&amp;gt;...&amp;gt;&amp;gt;&lt;br/&gt;{&lt;br/&gt;std::promise&amp;lt;&lt;br/&gt;std::invoke_result_t&amp;lt;std::decay_t&amp;lt;F&amp;gt;,&lt;br/&gt;std::decay_t&amp;lt;Args&amp;gt;...&amp;gt;&amp;gt; p;&lt;br/&gt;try {&lt;br/&gt;p.set_value(std::invoke(auto(f), auto(args)...));&lt;br/&gt;} catch (...) {&lt;br/&gt;p.set_exception(std::current_exception());&lt;br/&gt;}&lt;br/&gt;return p.get_future();&lt;br/&gt;}&lt;br/&gt;Or you could make packaged_task do the work for you:&lt;br/&gt;template&amp;lt;typename F, typename... Args&amp;gt;&lt;br/&gt;auto&lt;br/&gt;make_immediate_future(F&amp;amp;&amp;amp; f, Args&amp;amp;&amp;amp;... args)&lt;br/&gt;-&amp;gt; std::future&amp;lt;&lt;br/&gt;std::invoke_result_t&amp;lt;std::decay_t&amp;lt;F&amp;gt;,&lt;br/&gt;std::decay_t&amp;lt;Args&amp;gt;...&amp;gt;&amp;gt;&lt;br/&gt;{&lt;br/&gt;using R = std::invoke_result_t&amp;lt;std::decay_t&amp;lt;F&amp;gt;,&lt;br/&gt;std::decay_t&amp;lt;Args&amp;gt;...&amp;gt;;&lt;br/&gt;std::packaged_task&amp;lt;R(Args...)&amp;gt; task(f);&lt;br/&gt;task(args...);&lt;br/&gt;return task.get_future();&lt;br/&gt;}&lt;br/&gt;Yet another way would be to ask for an on-demand in-thread execution, and then immediately demand it.&lt;br/&gt;template&amp;lt;typename F, typename... Args&amp;gt;&lt;br/&gt;auto&lt;br/&gt;make_immediate_future(F&amp;amp;&amp;amp; f, Args&amp;amp;&amp;amp;... args)&lt;br/&gt;-&amp;gt; std::future&amp;lt;&lt;br/&gt;std::invoke_result_t&amp;lt;std::decay_t&amp;lt;F&amp;gt;,&lt;br/&gt;std::decay_t&amp;lt;Args&amp;gt;...&amp;gt;&amp;gt;&lt;br/&gt;{&lt;br/&gt;auto f = std::async(std::launch::deferred,&lt;br/&gt;std::forward&amp;lt;F&amp;gt;(f),&lt;br/&gt;std::forward&amp;lt;Args&amp;gt;(args)...);&lt;br/&gt;f.wait();&lt;br/&gt;return f;&lt;br/&gt;}&lt;br/&gt;The post C&#43;&#43; futures part 4: What if I want an immediate on-thread &amp;lt;CODE&amp;gt;std::async&amp;lt;/CODE&amp;gt;? appeared first on The Old New Thing.&lt;br/&gt;&lt;br/&gt;&lt;a href=&#34;https://devblogs.microsoft.com/oldnewthing/20261015-00/?p=112776/&#34;&gt;https://devblogs.microsoft.com/oldnewthing/20261015-00/?p=112776/&lt;/a&gt;
    </content>
    <updated>2026-10-16T03:43:26Z</updated>
  </entry>

</feed>