Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Configurable/Customizable options copyable #8704

Closed
wants to merge 3 commits into from

Conversation

mrambacher
Copy link
Contributor

The atomic variable "is_prepared_" was keeping Configurable objects from being copy-constructed. Removed the atomic to allow copies.

Since the variable is only changed from false to true (and never back), there is no reason it had to be atomic.

Added tests that simple Configurable and Customizable objects can be put on the stack and copied.

The atomic variable "is_prepared_" was keeping Configurable objects from being copy-constructed.  Removed the atomic to allow copies.

Since the variable is only changed from false to true (and never back), there is no reason it had to be atomic.

Added tests that simple Configurable and Customizable objects can be put on the stack and copied.
@facebook-github-bot
Copy link
Contributor

@mrambacher has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@@ -288,7 +288,7 @@ class Configurable {
protected:
// True once the object is prepared. Once the object is prepared, only
// mutable options can be configured.
std::atomic<bool> is_prepared_;
bool is_prepared_;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there's more to this. I did some more digging and actually made the same change locally, then ran the unit test suite under TSAN. A handful of remote compaction related UTs were flagged due to multiple threads racing to update this variable for the BytewiseComparator Meyers singleton while deserializing CompactionServiceInput (which includes the column family options). I'm assuming the reason the flag got turned into an atomic in #8336 in the first place was to make these warnings go away. It did not, however, solve the root cause of the issue, namely that it is not safe to use the Configurable / Customizable framework from multiple threads (without synchronization) in the presence of "global" objects like BytewiseComparator (which is what the compaction service does).

Also Cc @jay-zhuang because this affects remote compaction (and might be related to the flaky test you were looking at).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having said that, I support ditching the atomic since it only gives the illusion of thread safety. The race affecting the compaction service could be handled in a separate PR I think.

Copy link
Contributor

@ltamasi ltamasi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The race affecting the compaction service could be handled in a separate PR I think.

Actually, scratch that part. The issue affects more than remote compaction, see e.g. how DBTest2.MultiDBParallelOpenTest fails under TSAN. I think it would be best if we fixed this in this PR.

@facebook-github-bot
Copy link
Contributor

@mrambacher has updated the pull request. You must reimport the pull request before landing.

Comment on lines 22 to 26
Configurable::Configurable(const Configurable& o)
: is_prepared_(o.is_prepared_.load()) {
options_ = o.options_;
}

Copy link
Contributor

@ltamasi ltamasi Aug 25, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say let's remove is_prepared_ / IsPrepared altogether. Two reasons:

  1. It's unused except for unit tests.
  2. This is not thread-safe regardless of whether the flag is atomic or not because the interface is inherently thread-unsafe. I.e. in the presence of multiple threads, there is a race condition in the following even if you make the flag atomic because multiple threads may find the flag unset and proceed to call PrepareOptions:
if (!cfgable->IsPrepared()) {
   Status s = cfgable->PrepareOptions(cfg_options);
   // ...
}

@facebook-github-bot
Copy link
Contributor

@mrambacher has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@ltamasi has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

@ltamasi merged this pull request in 6e63e77.

ltamasi pushed a commit that referenced this pull request Aug 26, 2021
Summary:
The atomic variable "is_prepared_" was keeping Configurable objects from being copy-constructed.  Removed the atomic to allow copies.

Since the variable is only changed from false to true (and never back), there is no reason it had to be atomic.

Added tests that simple Configurable and Customizable objects can be put on the stack and copied.

Pull Request resolved: #8704

Reviewed By: anand1976

Differential Revision: D30530526

Pulled By: ltamasi

fbshipit-source-id: 4dd4439b3e5ad7fa396573d0b25d9fb709160576
yoori pushed a commit to yoori/rocksdb that referenced this pull request Nov 26, 2023
Summary:
The atomic variable "is_prepared_" was keeping Configurable objects from being copy-constructed.  Removed the atomic to allow copies.

Since the variable is only changed from false to true (and never back), there is no reason it had to be atomic.

Added tests that simple Configurable and Customizable objects can be put on the stack and copied.

Pull Request resolved: facebook/rocksdb#8704

Reviewed By: anand1976

Differential Revision: D30530526

Pulled By: ltamasi

fbshipit-source-id: 4dd4439b3e5ad7fa396573d0b25d9fb709160576
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants