8000 Better protection against multi-threading. · lethalbrains/arangodb@b37d8ff · GitHub
[go: up one dir, main page]

Skip to content

Commit b37d8ff

Browse files
committed
Better protection against multi-threading.
1 parent b5c87fb commit b37d8ff

File tree

2 files changed

+27
-8
lines changed

2 files changed

+27
-8
lines changed

arangod/Cluster/AgencyCallback.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ bool AgencyCallback::executeEmpty() {
9292
result = _cb(VPackSlice::noneSlice());
9393
}
9494

95+
CONDITION_LOCKER(locker, _cv);
9596
if (_useCv) {
96-
CONDITION_LOCKER(locker, _cv);
9797
_cv.signal();
9898
}
9999
return result;
@@ -107,8 +107,8 @@ bool AgencyCallback::execute(std::shared_ptr<VPackBuilder> newData) {
107107
result = _cb(newData->slice());
108108
}
109109

110+
CONDITION_LOCKER(locker, _cv);
110111
if (_useCv) {
111-
CONDITION_LOCKER(locker, _cv);
112112
_cv.signal();
113113
}
114114
return result;

arangod/Cluster/ClusterInfo.cpp

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -901,14 +901,19 @@ int ClusterInfo::createDatabaseCoordinator(std::string const& name,
901901
std::vector<ServerID> DBServers = getCurrentDBServers();
902902

903903
int dbServerResult = -1;
904+
904905
std::function<bool(VPackSlice const& result)> dbServerChanged =
905906
[&](VPackSlice const& result) {
906907
size_t numDbServers;
907908
{
908909
MUTEX_LOCKER(guard, dbServersMutex);
909910
numDbServers = DBServers.size();
910911
}
911-
if (result.isObject() && result.length() == numDbServers) {
912+
if (result.isObject() && result.length() >= numDbServers) {
913+
// We use >= here since the number of DBservers could have increased
914+
// during the creation of the database and we might not yet have
915+
// the latest list. Thus there could be more reports than we know
916+
// servers.
912917
VPackObjectIterator dbs(result);
913918

914919
std::string tmpMsg = "";
@@ -934,16 +939,24 @@ int ClusterInfo::createDatabaseCoordinator(std::string const& name,
934939
}
935940
}
936941
if (tmpHaveError) {
942+
MUTEX_LOCKER(guard, dbServersMutex);
937943
errorMsg = "Error in creation of database:" + tmpMsg;
938944
dbServerResult = TRI_ERROR_CLUSTER_COULD_NOT_CREATE_DATABASE;
939945
return true;
940946
}
941947
loadCurrent(); // update our cache
942-
dbServerResult = setErrormsg(TRI_ERROR_NO_ERROR, errorMsg);
948+
{
949+
MUTEX_LOCKER(guard, dbServersMutex);
950+
dbServerResult = setErrormsg(TRI_ERROR_NO_ERROR, errorMsg);
951+
}
943952
}
944953
return true;
945954
};
946955

956+
// ATTENTION: The following callback calls the above closure in a
957+
// different thread. Nevertheless, the closure accesses some of our
958+
// local variables. Therefore we have to protect all accesses to them
959+
// by the above mutex.
947960
auto agencyCallback = std::make_shared<AgencyCallback>(
948961
ac, "Current/Databases/" + name, dbServerChanged, true, false);
949962
_agencyCallbackRegistry->registerCallback(agencyCallback);
@@ -974,8 +987,11 @@ int ClusterInfo::createDatabaseCoordinator(std::string const& name,
974987
int count = 0; // this counts, when we have to reload the DBServers
975988
while (TRI_microtime() <= endTime) {
976989
agencyCallback->executeByCallbackOrTimeout(getReloadServerListTimeout() / interval);
977-
if (dbServerResult >= 0) {
978-
break;
990+
{
991+
MUTEX_LOCKER(guard, dbServersMutex);
992+
if (dbServerResult >= 0) {
993+
break;
994+
}
979995
}
980996

981997
if (++count >= static_cast<int>(getReloadServerListTimeout() / interval)) {
@@ -991,8 +1007,11 @@ int ClusterInfo::createDatabaseCoordinator(std::string const& name,
9911007
count = 0;
9921008
}
9931009
}
994-
if (dbServerResult >= 0) {
995-
return dbServerResult;
1010+
{
1011+
MUTEX_LOCKER(guard, dbServersMutex);
1012+
if (dbServerResult >= 0) {
1013+
return dbServerResult;
1014+
}
9961015
}
9971016
return setErrormsg(TRI_ERROR_CLUSTER_TIMEOUT, errorMsg);
9981017
}

0 commit comments

Comments
 (0)
0