diff options
Diffstat (limited to 'src/google/protobuf/map_field.cc')
-rw-r--r-- | src/google/protobuf/map_field.cc | 52 |
1 files changed, 31 insertions, 21 deletions
diff --git a/src/google/protobuf/map_field.cc b/src/google/protobuf/map_field.cc index 64dcc990..ac29c7e9 100644 --- a/src/google/protobuf/map_field.cc +++ b/src/google/protobuf/map_field.cc @@ -43,13 +43,15 @@ MapFieldBase::~MapFieldBase() { const RepeatedPtrFieldBase& MapFieldBase::GetRepeatedField() const { SyncRepeatedFieldWithMap(); - return *repeated_field_; + return *reinterpret_cast<::google::protobuf::internal::RepeatedPtrFieldBase*>( + repeated_field_); } RepeatedPtrFieldBase* MapFieldBase::MutableRepeatedField() { SyncRepeatedFieldWithMap(); SetRepeatedDirty(); - return repeated_field_; + return reinterpret_cast<::google::protobuf::internal::RepeatedPtrFieldBase*>( + repeated_field_); } size_t MapFieldBase::SpaceUsedExcludingSelfLong() const { @@ -70,29 +72,39 @@ size_t MapFieldBase::SpaceUsedExcludingSelfNoLock() const { bool MapFieldBase::IsMapValid() const { // "Acquire" insures the operation after SyncRepeatedFieldWithMap won't get // executed before state_ is checked. - Atomic32 state = google::protobuf::internal::Acquire_Load(&state_); + int state = state_.load(std::memory_order_acquire); return state != STATE_MODIFIED_REPEATED; } -void MapFieldBase::SetMapDirty() { state_ = STATE_MODIFIED_MAP; } +bool MapFieldBase::IsRepeatedFieldValid() const { + int state = state_.load(std::memory_order_acquire); + return state != STATE_MODIFIED_MAP; +} + +void MapFieldBase::SetMapDirty() { + // These are called by (non-const) mutator functions. So by our API it's the + // callers responsibility to have these calls properly ordered. + state_.store(STATE_MODIFIED_MAP, std::memory_order_relaxed); +} -void MapFieldBase::SetRepeatedDirty() { state_ = STATE_MODIFIED_REPEATED; } +void MapFieldBase::SetRepeatedDirty() { + // These are called by (non-const) mutator functions. So by our API it's the + // callers responsibility to have these calls properly ordered. + state_.store(STATE_MODIFIED_REPEATED, std::memory_order_relaxed); +} void* MapFieldBase::MutableRepeatedPtrField() const { return repeated_field_; } void MapFieldBase::SyncRepeatedFieldWithMap() const { - // "Acquire" insures the operation after SyncRepeatedFieldWithMap won't get - // executed before state_ is checked. - Atomic32 state = google::protobuf::internal::Acquire_Load(&state_); - if (state == STATE_MODIFIED_MAP) { + // acquire here matches with release below to ensure that we can only see a + // value of CLEAN after all previous changes have been synced. + if (state_.load(std::memory_order_acquire) == STATE_MODIFIED_MAP) { mutex_.Lock(); // Double check state, because another thread may have seen the same state // and done the synchronization before the current thread. - if (state_ == STATE_MODIFIED_MAP) { + if (state_.load(std::memory_order_relaxed) == STATE_MODIFIED_MAP) { SyncRepeatedFieldWithMapNoLock(); - // "Release" insures state_ can only be changed "after" - // SyncRepeatedFieldWithMapNoLock is finished. - google::protobuf::internal::Release_Store(&state_, CLEAN); + state_.store(CLEAN, std::memory_order_release); } mutex_.Unlock(); } @@ -105,18 +117,15 @@ void MapFieldBase::SyncRepeatedFieldWithMapNoLock() const { } void MapFieldBase::SyncMapWithRepeatedField() const { - // "Acquire" insures the operation after SyncMapWithRepeatedField won't get - // executed before state_ is checked. - Atomic32 state = google::protobuf::internal::Acquire_Load(&state_); - if (state == STATE_MODIFIED_REPEATED) { + // acquire here matches with release below to ensure that we can only see a + // value of CLEAN after all previous changes have been synced. + if (state_.load(std::memory_order_acquire) == STATE_MODIFIED_REPEATED) { mutex_.Lock(); // Double check state, because another thread may have seen the same state // and done the synchronization before the current thread. - if (state_ == STATE_MODIFIED_REPEATED) { + if (state_.load(std::memory_order_relaxed) == STATE_MODIFIED_REPEATED) { SyncMapWithRepeatedFieldNoLock(); - // "Release" insures state_ can only be changed "after" - // SyncRepeatedFieldWithMapNoLock is finished. - google::protobuf::internal::Release_Store(&state_, CLEAN); + state_.store(CLEAN, std::memory_order_release); } mutex_.Unlock(); } @@ -130,6 +139,7 @@ DynamicMapField::DynamicMapField(const Message* default_entry) DynamicMapField::DynamicMapField(const Message* default_entry, Arena* arena) : TypeDefinedMapFieldBase<MapKey, MapValueRef>(arena), + map_(arena), default_entry_(default_entry) { } |