microsoft / microsoft/STL

`<thread>`: `promise::set_value_at_thread_exit` sets the value too early

Open
#3,614 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug vNext
Dominant language
C++
Stars
11.2k
Forks
1.7k
Avg merge
4d 15h
Merged PRs (30d)
22

Description

Describe the bug
from https://en.cppreference.com/w/cpp/thread/promise/set_value_at_thread_exit

Stores the value into the shared state without making the state ready immediately. The state is made ready when the current thread exits, after all variables with thread-local storage duration have been destroyed.

but this is not true for our implementation.

This is probably a known issue because I found a comment in the implementation // TRANSITION, ABI but I didn't find a github issue about it so I decided to create it.

Command-line test case

C:\Temp>type main.cpp
#include<iostream>
#include<future>
using namespace std;

struct foo {
	~foo() { cout << "~foo() "; }
};

int main() {
	promise<void> prom;
	future<void> f = prom.get_future();
	thread t([&prom] {
		thread_local foo foo;
		prom.set_value_at_thread_exit();
	});
	f.get();
	cout << "gotten ";
	t.join();
}

C:\Temp>cl /EHsc /W4 /WX .\main.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.36.32502 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

main.cpp
Microsoft (R) Incremental Linker Version 14.36.32502.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:main.exe
main.obj

C:\Temp>main.exe
gotten ~foo()

Expected behavior
The output should be “~foo() gotten”

STL version

    Microsoft Visual Studio Community 2022 Preview
    Version 17.6.0 Preview 2.0

Additional context
DevCom-10322768 and internal VSO-1779407 / AB#1779407

I played with the example a bit and I think this line is wrong:

https://github.com/microsoft/STL/blob/9231abe46d466a0f262db234fd3bd4de1170ee45/stl/inc/thread#L56

I added more details to Devcom-10322768 as my comment

If we could use thread_local in STL we could add a thread_local struct and call _Cnd_do_broadcast_at_thread_exit in its destructor...

vNext note: Resolving this issue will require breaking binary compatibility. We won't be able to accept pull requests for this issue until the vNext branch is available. See https://github.com/microsoft/STL/issues/169 for more information.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with stl/inc/thread at the referenced line around 56, then run the command-line test case from the issue to observe the ordering of the output. The fix is complete when set_value_at_thread_exit makes the future ready only after thread-local destruction, while accounting for the stated vNext ABI-compatibility constraint.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
operating-systems
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.