Is it possible to safely move unique_ptr with c++11 atomic operations?
Currently I have a code like this
std::unique_ptr<SyncToken> DataManager::borrowSyncToken()
{
std::unique_lock<std::mutex> syncTokenLock(syncTokenMutex);
return std::move(syncToken);
}
I am wondering whether there is some more elegant way, like simply declaring:
std::atomic<std::unique_ptr<SyncToken>> syncToken;
and avoiding the need of mutex. Or possibly I don't need to care about the lock here at all and std::move is already atomic?
After research I made so far it seems to me:
No, this is not possible.
The value T
which you pass to std::atomic
needs to be trivially copyable, which std::unique_ptr
is not. Operations like std::atomic::load
or std::atomic::store
take T objects by value.
Packing something in a std::atomic
also doesn't make operations from the value atomic.
When using std::unique_ptr
in an atomic context, you have to think about the fact that you might have problems when it comes to managing resources. You never know how many threads still refer to your data, this problem can be solved with a std::shared_ptr
which uses atomic reference counting. (You need to check whether it's really atomic by using the std::atomic_is_lock_free
function. )
One thing I was also stumbling upon when looking in your code is the intent of the borrowSyncToken
function. It's called borrow but you pass ownership of the token to the caller by moving out the std::unique_ptr
, how is the ownership passed back and what do other threads get when the DataManager currently doesn't own the token?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With