Now r holds a reference to the object that was pointed by q. Even if p.reset() is executed in another thread, the object will stay alive until r goes out of scope or is reset. By obtaining a shared_ptr to the object, we have effectively locked it against destruction.
---
Теперь собственно сам вопрос, возможно ли вместо копирования указателя, "стандартными средствами" boost заблокировать нить пытающуюся удалить объект на который существует слабая ссылка weak_ptr.
В чем собственно проблема:
Нельзя создавать shared_ptr из weak_ptr в потоке А, зная что в другом потоке (Б) объект (вернее его shared_ptr) может быть удален. Владельцем указателя является поток Б. Именно он определяет время, как указателя так соответственно и инстанса. "Нельзя" не потому что я доку неправильно прочитал, а такова постановка задачи.
То-есть если в потоке Б, было принято решение указатель удалить, то поток А должен получить фигу в виде weak_ptr::get() == NULL, если поток А в данный момент еще (или уже) использует указатель, то поток Б обязан ждать, хоть до морковкиного заговения, но указатель не удалять.
Использование
if(int * r = q.get())
{
// use *r
}
приведет к нарушению защиты памяти, и инвалидации указателя.
Использование
if(shared_ptr<int> r = q.lock())
{
// use *r
}
приведет к неблокируемому удалению указателя в потоке Б.
Я вижу 2 варианта:
1. Сделать блокирующий фасад над shared_ptr/weak_ptr.
2. искорёжить weak_ptr::get() и деструкотр shared_ptr.
1-й вариант конечно "правильный", 2-й вариант безобразный и must die.
Вопрос к многоуважаемому All, есть ли другие варианты ?
Учитывая, что shared_ptr уже thread safe, наворачивать фассад с дополнительным мъютексом видится мне как удвоение времени операции доступа к данным. Что в конечном итоге скажется (и очень) на общей производительности системы.