Skip to content

Commit 584754c

Browse files
committed
Fix race between clear_and_update_back and update_partitions
1 parent 4f2faf2 commit 584754c

2 files changed

Lines changed: 23 additions & 19 deletions

File tree

src/metadata.cpp

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -788,15 +788,15 @@ std::string Metadata::full_function_name(const std::string& name, const StringVe
788788

789789
Metadata::SchemaSnapshot Metadata::schema_snapshot(int protocol_version, const VersionNumber& cassandra_version) const {
790790
ScopedMutex l(&mutex_);
791-
return SchemaSnapshot(schema_snapshot_version_,
791+
return SchemaSnapshot(schema_snapshot_version_.load(),
792792
protocol_version,
793793
cassandra_version,
794794
front_.keyspaces(),
795795
front_.partitions());
796796
}
797797

798798
void Metadata::update_keyspaces(int protocol_version, const VersionNumber& cassandra_version, ResultResponse* result) {
799-
schema_snapshot_version_++;
799+
schema_snapshot_version_.fetch_add(1);
800800

801801
if (is_front_buffer()) {
802802
ScopedMutex l(&mutex_);
@@ -807,7 +807,7 @@ void Metadata::update_keyspaces(int protocol_version, const VersionNumber& cassa
807807
}
808808

809809
void Metadata::update_tables(int protocol_version, const VersionNumber& cassandra_version, ResultResponse* result) {
810-
schema_snapshot_version_++;
810+
schema_snapshot_version_.fetch_add(1);
811811

812812
if (is_front_buffer()) {
813813
ScopedMutex l(&mutex_);
@@ -818,7 +818,7 @@ void Metadata::update_tables(int protocol_version, const VersionNumber& cassandr
818818
}
819819

820820
void Metadata::update_views(int protocol_version, const VersionNumber& cassandra_version, ResultResponse* result) {
821-
schema_snapshot_version_++;
821+
schema_snapshot_version_.fetch_add(1);
822822

823823
if (is_front_buffer()) {
824824
ScopedMutex l(&mutex_);
@@ -829,7 +829,7 @@ void Metadata::update_views(int protocol_version, const VersionNumber& cassandra
829829
}
830830

831831
void Metadata::update_columns(int protocol_version, const VersionNumber& cassandra_version, ResultResponse* result) {
832-
schema_snapshot_version_++;
832+
schema_snapshot_version_.fetch_add(1);
833833

834834
if (is_front_buffer()) {
835835
ScopedMutex l(&mutex_);
@@ -846,7 +846,7 @@ void Metadata::update_columns(int protocol_version, const VersionNumber& cassand
846846
}
847847

848848
void Metadata::update_indexes(int protocol_version, const VersionNumber& cassandra_version, ResultResponse* result) {
849-
schema_snapshot_version_++;
849+
schema_snapshot_version_.fetch_add(1);
850850

851851
if (is_front_buffer()) {
852852
ScopedMutex l(&mutex_);
@@ -857,7 +857,7 @@ void Metadata::update_indexes(int protocol_version, const VersionNumber& cassand
857857
}
858858

859859
void Metadata::update_user_types(int protocol_version, const VersionNumber& cassandra_version, ResultResponse* result) {
860-
schema_snapshot_version_++;
860+
schema_snapshot_version_.fetch_add(1);
861861

862862
if (is_front_buffer()) {
863863
ScopedMutex l(&mutex_);
@@ -868,7 +868,7 @@ void Metadata::update_user_types(int protocol_version, const VersionNumber& cass
868868
}
869869

870870
void Metadata::update_functions(int protocol_version, const VersionNumber& cassandra_version, ResultResponse* result) {
871-
schema_snapshot_version_++;
871+
schema_snapshot_version_.fetch_add(1);
872872

873873
if (is_front_buffer()) {
874874
ScopedMutex l(&mutex_);
@@ -879,7 +879,7 @@ void Metadata::update_functions(int protocol_version, const VersionNumber& cassa
879879
}
880880

881881
void Metadata::update_aggregates(int protocol_version, const VersionNumber& cassandra_version, ResultResponse* result) {
882-
schema_snapshot_version_++;
882+
schema_snapshot_version_.fetch_add(1);
883883

884884
if (is_front_buffer()) {
885885
ScopedMutex l(&mutex_);
@@ -891,12 +891,12 @@ void Metadata::update_aggregates(int protocol_version, const VersionNumber& cass
891891

892892
void Metadata::update_partitions(int protocol_version, const VersionNumber& cassandra_version, ResultResponse* result) {
893893
ScopedMutex l(&mutex_);
894-
schema_snapshot_version_++;
894+
schema_snapshot_version_.fetch_add(1);
895895
updating_->update_partitions(protocol_version, cassandra_version, cache_, result);
896896
}
897897

898898
void Metadata::drop_keyspace(const std::string& keyspace_name) {
899-
schema_snapshot_version_++;
899+
schema_snapshot_version_.fetch_add(1);
900900

901901
if (is_front_buffer()) {
902902
ScopedMutex l(&mutex_);
@@ -907,7 +907,7 @@ void Metadata::drop_keyspace(const std::string& keyspace_name) {
907907
}
908908

909909
void Metadata::drop_table_or_view(const std::string& keyspace_name, const std::string& table_or_view_name) {
910-
schema_snapshot_version_++;
910+
schema_snapshot_version_.fetch_add(1);
911911

912912
if (is_front_buffer()) {
913913
ScopedMutex l(&mutex_);
@@ -918,7 +918,7 @@ void Metadata::drop_table_or_view(const std::string& keyspace_name, const std::s
918918
}
919919

920920
void Metadata::drop_user_type(const std::string& keyspace_name, const std::string& type_name) {
921-
schema_snapshot_version_++;
921+
schema_snapshot_version_.fetch_add(1);
922922

923923
if (is_front_buffer()) {
924924
ScopedMutex l(&mutex_);
@@ -929,7 +929,7 @@ void Metadata::drop_user_type(const std::string& keyspace_name, const std::strin
929929
}
930930

931931
void Metadata::drop_function(const std::string& keyspace_name, const std::string& full_function_name) {
932-
schema_snapshot_version_++;
932+
schema_snapshot_version_.fetch_add(1);
933933

934934
if (is_front_buffer()) {
935935
ScopedMutex l(&mutex_);
@@ -940,7 +940,7 @@ void Metadata::drop_function(const std::string& keyspace_name, const std::string
940940
}
941941

942942
void Metadata::drop_aggregate(const std::string& keyspace_name, const std::string& full_aggregate_name) {
943-
schema_snapshot_version_++;
943+
schema_snapshot_version_.fetch_add(1);
944944

945945
if (is_front_buffer()) {
946946
ScopedMutex l(&mutex_);
@@ -952,23 +952,27 @@ void Metadata::drop_aggregate(const std::string& keyspace_name, const std::strin
952952

953953
void Metadata::clear_and_update_back(const VersionNumber& cassandra_version) {
954954
back_.clear();
955+
// ASAN revealed that clear_and_update_back may race with update_partitions.
956+
// Obtain lock via mutex_ to guard updating_.
957+
// There shouldn't be deadlock because the caller doesn't hold other lock.
958+
ScopedMutex l(&mutex_);
955959
updating_ = &back_;
956960
}
957961

958962
void Metadata::swap_to_back_and_update_front() {
959963
{
960964
ScopedMutex l(&mutex_);
961-
schema_snapshot_version_++;
965+
schema_snapshot_version_.fetch_add(1);
962966
front_.swap(back_);
967+
updating_ = &front_;
963968
}
964969
back_.clear();
965-
updating_ = &front_;
966970
}
967971

968972
void Metadata::clear() {
969973
{
970974
ScopedMutex l(&mutex_);
971-
schema_snapshot_version_ = 0;
975+
schema_snapshot_version_.store(0);
972976
front_.clear();
973977
}
974978
back_.clear();

src/metadata.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -831,7 +831,7 @@ class Metadata {
831831
InternalData front_;
832832
InternalData back_;
833833

834-
uint32_t schema_snapshot_version_;
834+
Atomic<uint32_t> schema_snapshot_version_;
835835

836836
// This lock prevents partial snapshots when updating metadata
837837
mutable uv_mutex_t mutex_;

0 commit comments

Comments
 (0)