When I was looking for how to implement copy-on-write in C++, I saw the implementation as below:
#include <iostream>
#include <string>
#include <memory>
using namespace std;
struct SPersonData
{
string m_name;
string m_surname;
};
class CPerson
{
public:
shared_ptr<SPersonData> m_data;
string getName() const;
string getSurname() const;
void rename (const string&, const string&);
};
string CPerson::getName() const
{
if (m_data) return m_data->m_name;
return string();
}
string CPerson::getSurname() const
{
if (m_data) return m_data->m_surname;
return string();
}
void CPerson::rename (const string &name, const string &surname)
{
if (!((m_data) && m_data.unique()))
m_data = make_shared<SPersonData>();
m_data->m_name = name;
m_data->m_surname = surname;
}
However, I am very curious of that how it ensure the thread safety. First, I know the shared_ptr is not thread-safe so it may cause the object in shared_ptr released improperly if other threads are accessing the shared_ptr at the same time when some threads are changing shared_ptr as below.
if (!((m_data) && m_data.unique()))
m_data = make_shared<SPersonData>();
Secondly, on rename() method, changing shared_ptr and assigning value are not atomic so if other threads try accessing the shared_ptr value in between the thread changes the shared_ptr and assignes the value, they may get the wrong value.
How to correctly implement copy-on-write in C++?
7