This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug libstdc++/60966] std::call_once sometime hangs
- From: "hideaki.kimura at gmail dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Fri, 16 May 2014 00:05:46 +0000
- Subject: [Bug libstdc++/60966] std::call_once sometime hangs
- Auto-submitted: auto-generated
- References: <bug-60966-4 at http dot gcc dot gnu dot org/bugzilla/>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60966
--- Comment #22 from Hideaki Kimura <hideaki.kimura at gmail dot com> ---
Ah, you are right, set_value() might have context switch after signaling before
exitting.
... ah, and that's why what Thomas initially posted could also see a hang.
{ // copy-paste again to refresh memory, with some simplification
std::promise<void> promise;
auto future = promise.get_future();
std::async or thread ( {promise.set_value();});
future.get();
}
The user of std::promise must make sure the asynchronous thread has surely
exitted at least from promise.set_value() before std::promise gets out of
scope.
promise/future is a handy way to synchronize between threads, but to use it one
must protect it with thread synchronization..? That's quite tedious.
I've just seen the patch as of writing this comment. I guess it solves the
issue?
(In reply to Jonathan Wakely from comment #19)
> (In reply to Jonathan Wakely from comment #16)
> > The easiest fix is to call get_future() before passing the task into a new
> > thread, and store it in a std::vector<std::future<void>>
>
> Actually this only hides the error (by ensuring the shared state is not
> deleted
> because there is a future object still referring to it) but the fundamental
> problem with that code remains:
>
> You are calling the promise destructor before the call to set_value()
> completes.
>
> You are assuming that as soon as the shared state becomes ready the promise
> is no longer in use, but that's not true. After the shared state is made
> ready the rest of the set_value() function runs, which accesses members of
> the shared state. If you destroy the promise (and it has the only reference
> to the shared state) then it will destroy its members while they are still
> being used.
>
> This is a bug in your code, std::promise is like any other type: you must
> not delete it while another thread is still using it.