[patch] libstdc++/60966 fix synchronisation in std::promise

Jonathan Wakely jwakely@redhat.com
Sat May 17 13:08:00 GMT 2014


This patch implements the correct synchronisation guarantees for
promise::set_value() and promise:;set_exception, so that successful
calls to those functions synchronize with functions that detect the
ready state.

Previously a waiting function could detect a ready state as soon as
the result was stored into the state, but before signalling the
condition variable or returning from std::call_once(). That meant a
waiting function might destroy the std::promise thinking it was
finished with. If the promise released the last reference to the
shared state it would invalidate the pthread_once_t and pthread_cond_t
objects which were still in use.

With this change the lock is held until after the once flag and
condvar have been used, so readiness of the state cannot be detected
until _M_set_result returns. (Note that we still don't take the lock
until after running the setter, since that might be running arbitrary
user-defined code in copy constructors or callable tasks which could
deadlock or result in undefined behaviour if called with the lock held
... not all implementations get this right!)

The second patch is for the release branches, where instead of
changing the function signatures I just take an extra reference to the
shared state in the set_value() and set_exception() members, so that
if the promise is destroyed as soon as the state is made ready it
doesn't release the last refererence and the shared state isn't
destroyed too soon.

Tested x86_64-linux, committed to trunk and 4.9, with a commit to
follow for 4.8 after the branch re-opens.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: patch.txt
Type: text/x-patch
Size: 5042 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/libstdc++/attachments/20140517/6cda5770/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: patch-49.txt
Type: text/x-patch
Size: 6494 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/libstdc++/attachments/20140517/6cda5770/attachment-0001.bin>


More information about the Libstdc++ mailing list