Skip to content

Review LazyObjectImpl::obj() #696

@alandefreitas

Description

@alandefreitas

Most compilers don't implement __cpp_lib_atomic_shared_ptr, on which LazyObjectImpl depends:

ObjectImpl&
LazyObjectImpl::
obj() const
{
#ifdef __cpp_lib_atomic_shared_ptr
auto impl = sp_.load();
if(impl)
return *impl;
impl_type expected = nullptr;
if(sp_.compare_exchange_strong(
expected, construct().impl()))
return *sp_.load();
return *expected;
#else
return *sp_;
#endif
}

For this reason, the function above contains two implementations, depending on whether __cpp_lib_atomic_shared_ptr is supported.

Both implementations are problematic:

  • The implementation is not thread-safe when __cpp_lib_atomic_shared_ptr is unsupported. The object would need to carry a pointer to mutex for that.
  • The implementation when __cpp_lib_atomic_shared_ptr is supported is also unsafe because the load and exchange operations are independent. This means two concurrent threads will attempt to construct the object twice if they call the function before the object is constructed.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions