From bc6fce75d457edccad15032c30ec277421433906 Mon Sep 17 00:00:00 2001 From: Jan Steemann Date: Tue, 2 Feb 2016 12:13:21 +0100 Subject: [PATCH 1/6] removed some unnecessary explicits --- arangod/Aql/AstNode.h | 8 ++++---- arangod/Indexes/PathBasedIndex.h | 2 +- arangod/Scheduler/SocketTask.h | 2 +- arangod/V8Server/V8Traverser.h | 2 +- arangod/Wal/CollectorThread.h | 2 +- arangod/Wal/Marker.h | 2 +- lib/Basics/JsonHelper.h | 26 +++++++++++++------------- 7 files changed, 22 insertions(+), 22 deletions(-) diff --git a/arangod/Aql/AstNode.h b/arangod/Aql/AstNode.h index 03cb6a2d87..df72dc27e3 100644 --- a/arangod/Aql/AstNode.h +++ b/arangod/Aql/AstNode.h @@ -219,25 +219,25 @@ struct AstNode { /// @brief create a node, with defining a value type ////////////////////////////////////////////////////////////////////////////// - explicit AstNode(AstNodeType, AstNodeValueType); + AstNode(AstNodeType, AstNodeValueType); ////////////////////////////////////////////////////////////////////////////// /// @brief create a boolean node, with defining a value type ////////////////////////////////////////////////////////////////////////////// - explicit AstNode(bool, AstNodeValueType); + AstNode(bool, AstNodeValueType); ////////////////////////////////////////////////////////////////////////////// /// @brief create a boolean node, with defining a value type ////////////////////////////////////////////////////////////////////////////// - explicit AstNode(int64_t, AstNodeValueType); + AstNode(int64_t, AstNodeValueType); ////////////////////////////////////////////////////////////////////////////// /// @brief create a string node, with defining a value type ////////////////////////////////////////////////////////////////////////////// - explicit AstNode(char const*, size_t, AstNodeValueType); + AstNode(char const*, size_t, AstNodeValueType); ////////////////////////////////////////////////////////////////////////////// /// @brief create the node from JSON diff --git a/arangod/Indexes/PathBasedIndex.h b/arangod/Indexes/PathBasedIndex.h index 526f35d1d7..3bab86f3bf 100644 --- a/arangod/Indexes/PathBasedIndex.h +++ b/arangod/Indexes/PathBasedIndex.h @@ -69,7 +69,7 @@ class PathBasedIndex : public Index { std::vector> const&, bool unique, bool sparse, bool allowPartialIndex); - explicit PathBasedIndex(VPackSlice const&, bool); + PathBasedIndex(VPackSlice const&, bool); ~PathBasedIndex(); diff --git a/arangod/Scheduler/SocketTask.h b/arangod/Scheduler/SocketTask.h index 1775ce1c89..1b51b5d242 100644 --- a/arangod/Scheduler/SocketTask.h +++ b/arangod/Scheduler/SocketTask.h @@ -63,7 +63,7 @@ class SocketTask : virtual public Task, public ConnectionStatisticsAgent { ////////////////////////////////////////////////////////////////////////////// public: - explicit SocketTask(TRI_socket_t, double); + SocketTask(TRI_socket_t, double); ////////////////////////////////////////////////////////////////////////////// /// @brief deletes a socket task diff --git a/arangod/V8Server/V8Traverser.h b/arangod/V8Server/V8Traverser.h index bf8b869a0b..f26beda37c 100644 --- a/arangod/V8Server/V8Traverser.h +++ b/arangod/V8Server/V8Traverser.h @@ -203,7 +203,7 @@ class DepthFirstTraverser : public Traverser { class EdgeGetter { public: - explicit EdgeGetter(DepthFirstTraverser* traverser, + EdgeGetter(DepthFirstTraverser* traverser, TraverserOptions const& opts, CollectionNameResolver* resolver, Transaction* trx) : _traverser(traverser), _resolver(resolver), _opts(opts), _trx(trx) {} diff --git a/arangod/Wal/CollectorThread.h b/arangod/Wal/CollectorThread.h index 03115de707..35e48d9885 100644 --- a/arangod/Wal/CollectorThread.h +++ b/arangod/Wal/CollectorThread.h @@ -71,7 +71,7 @@ struct CollectorCache { CollectorCache(CollectorCache const&) = delete; CollectorCache& operator=(CollectorCache const&) = delete; - explicit CollectorCache(TRI_voc_cid_t collectionId, TRI_voc_tick_t databaseId, + CollectorCache(TRI_voc_cid_t collectionId, TRI_voc_tick_t databaseId, Logfile* logfile, int64_t totalOperationsCount, size_t operationsSize) : collectionId(collectionId), diff --git a/arangod/Wal/Marker.h b/arangod/Wal/Marker.h index dc62e8a3c4..0d0d3dfb46 100644 --- a/arangod/Wal/Marker.h +++ b/arangod/Wal/Marker.h @@ -387,7 +387,7 @@ class Marker { class EnvelopeMarker : public Marker { public: - explicit EnvelopeMarker(TRI_df_marker_t const*, TRI_voc_fid_t); + EnvelopeMarker(TRI_df_marker_t const*, TRI_voc_fid_t); ~EnvelopeMarker(); }; diff --git a/lib/Basics/JsonHelper.h b/lib/Basics/JsonHelper.h index 5d57383676..858ad4509c 100644 --- a/lib/Basics/JsonHelper.h +++ b/lib/Basics/JsonHelper.h @@ -345,7 +345,7 @@ class Json { ////////////////////////////////////////////////////////////////////////////// public: - explicit Json() + Json() : _json(nullptr), _zone(TRI_MemoryZoneId(TRI_UNKNOWN_MEM_ZONE)), _autofree(AUTOFREE) {} @@ -365,7 +365,7 @@ class Json { /// @brief generic constructor for a memzone and a type_e ////////////////////////////////////////////////////////////////////////////// - explicit Json(TRI_memory_zone_t* z, type_e t, autofree_e autofree = AUTOFREE) + Json(TRI_memory_zone_t* z, type_e t, autofree_e autofree = AUTOFREE) : _json(nullptr), _zone(TRI_MemoryZoneId(z)), _autofree(autofree) { make(t, 0); } @@ -374,7 +374,7 @@ class Json { /// @brief generic constructor for a type_e with a size hint ////////////////////////////////////////////////////////////////////////////// - explicit Json(type_e t, size_t sizeHint, autofree_e autofree = AUTOFREE) + Json(type_e t, size_t sizeHint, autofree_e autofree = AUTOFREE) : _json(nullptr), _zone(TRI_MemoryZoneId(TRI_UNKNOWN_MEM_ZONE)), _autofree(autofree) { @@ -385,7 +385,7 @@ class Json { /// @brief generic constructor for a memzone, a type_e and a size hint ////////////////////////////////////////////////////////////////////////////// - explicit Json(TRI_memory_zone_t* z, type_e t, size_t sizeHint, + Json(TRI_memory_zone_t* z, type_e t, size_t sizeHint, autofree_e autofree = AUTOFREE) : _json(nullptr), _zone(TRI_MemoryZoneId(z)), _autofree(autofree) { make(t, sizeHint); @@ -410,7 +410,7 @@ class Json { /// @brief constructor for a memzone and a bool ////////////////////////////////////////////////////////////////////////////// - explicit Json(TRI_memory_zone_t* z, bool x, autofree_e autofree = AUTOFREE) + Json(TRI_memory_zone_t* z, bool x, autofree_e autofree = AUTOFREE) : _json(nullptr), _zone(TRI_MemoryZoneId(z)), _autofree(autofree) { _json = TRI_CreateBooleanJson(z, x); @@ -438,7 +438,7 @@ class Json { /// @brief constructor for a memzone and an int32_t ////////////////////////////////////////////////////////////////////////////// - explicit Json(TRI_memory_zone_t* z, int32_t x, autofree_e autofree = AUTOFREE) + Json(TRI_memory_zone_t* z, int32_t x, autofree_e autofree = AUTOFREE) : _json(nullptr), _zone(TRI_MemoryZoneId(z)), _autofree(autofree) { _json = TRI_CreateNumberJson(z, static_cast(x)); @@ -466,7 +466,7 @@ class Json { /// @brief constructor for a memzone and a double ////////////////////////////////////////////////////////////////////////////// - explicit Json(TRI_memory_zone_t* z, double x, autofree_e autofree = AUTOFREE) + Json(TRI_memory_zone_t* z, double x, autofree_e autofree = AUTOFREE) : _json(nullptr), _zone(TRI_MemoryZoneId(z)), _autofree(autofree) { _json = TRI_CreateNumberJson(z, x); @@ -494,7 +494,7 @@ class Json { /// @brief constructor for a char const* ////////////////////////////////////////////////////////////////////////////// - explicit Json(char const* x, size_t length, autofree_e autofree = AUTOFREE) + Json(char const* x, size_t length, autofree_e autofree = AUTOFREE) : _json(nullptr), _zone(TRI_MemoryZoneId(TRI_UNKNOWN_MEM_ZONE)), _autofree(autofree) { @@ -509,7 +509,7 @@ class Json { /// @brief constructor for a memzone and a char const* ////////////////////////////////////////////////////////////////////////////// - explicit Json(TRI_memory_zone_t* z, char const* x, + Json(TRI_memory_zone_t* z, char const* x, autofree_e autofree = AUTOFREE) : _json(nullptr), _zone(TRI_MemoryZoneId(z)), _autofree(autofree) { _json = TRI_CreateStringCopyJson(z, x, strlen(x)); @@ -523,7 +523,7 @@ class Json { /// @brief constructor for a memzone and a char const* ////////////////////////////////////////////////////////////////////////////// - explicit Json(TRI_memory_zone_t* z, char const* x, size_t length, + Json(TRI_memory_zone_t* z, char const* x, size_t length, autofree_e autofree = AUTOFREE) : _json(nullptr), _zone(TRI_MemoryZoneId(z)), _autofree(autofree) { _json = TRI_CreateStringCopyJson(z, x, length); @@ -552,7 +552,7 @@ class Json { /// @brief constructor for a memzone and a string ////////////////////////////////////////////////////////////////////////////// - explicit Json(TRI_memory_zone_t* z, std::string const& x, + Json(TRI_memory_zone_t* z, std::string const& x, autofree_e autofree = AUTOFREE) : _json(nullptr), _zone(TRI_MemoryZoneId(z)), _autofree(autofree) { _json = TRI_CreateStringCopyJson(z, x.c_str(), x.size()); @@ -566,7 +566,7 @@ class Json { /// @brief constructor for a memzone and a TRI_json_t* ////////////////////////////////////////////////////////////////////////////// - explicit Json(TRI_memory_zone_t* z, TRI_json_t* j, + Json(TRI_memory_zone_t* z, TRI_json_t* j, autofree_e autofree = AUTOFREE) : _json(j), _zone(TRI_MemoryZoneId(z)), _autofree(autofree) {} @@ -574,7 +574,7 @@ class Json { /// @brief constructor for a memzone and a const TRI_json_t* ////////////////////////////////////////////////////////////////////////////// - explicit Json(TRI_memory_zone_t* z, TRI_json_t const* j, + Json(TRI_memory_zone_t* z, TRI_json_t const* j, autofree_e autofree = NOFREE) : _json(const_cast(j)), _zone(TRI_MemoryZoneId(z)), From 3709cd823e6a7e554739058229b756c8027d70c1 Mon Sep 17 00:00:00 2001 From: Frank Celler Date: Tue, 2 Feb 2016 12:56:25 +0100 Subject: [PATCH 2/6] generate UNITTEST_RESULT_CRASHED, use inspect, set defaults --- UnitTests/unittest.js | 153 ++++++++++++++++++++++++------------------ 1 file changed, 86 insertions(+), 67 deletions(-) diff --git a/UnitTests/unittest.js b/UnitTests/unittest.js index 5c7085015c..27dc44fab7 100644 --- a/UnitTests/unittest.js +++ b/UnitTests/unittest.js @@ -3,117 +3,129 @@ 'use strict'; const yaml = require("js-yaml"); +const _ = require("lodash"); const UnitTest = require("@arangodb/testing"); const internalMembers = UnitTest.internalMembers; const fs = require("fs"); const internal = require("internal"); +const inspect = internal.inspect; function makePathGeneric(path) { return path.split(fs.pathSeparator); } +function xmlEscape(s) { + return s.replace(/[<>&"]/g, function(c) { + return "&" + { + "<": "lt", + ">": "gt", + "&": "amp", + "\"": "quot" + }[c] + ";"; + }); +} + +function buildXml() { + let xml = ["\n"]; + + xml.text = function(s) { + Array.prototype.push.call(this, s); + return this; + }; + + xml.elem = function(tagName, attrs, close) { + this.text("<").text(tagName); + attrs = attrs || {}; + + for (let a in attrs) { + if (attrs.hasOwnProperty(a)) { + this.text(" ").text(a).text("=\"") + .text(xmlEscape(String(attrs[a]))).text("\""); + } + } + + if (close) { + this.text("/"); + } + + this.text(">\n"); + + return this; + }; + + return xml; +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief converts results to XML representation +//////////////////////////////////////////////////////////////////////////////// + function resultsToXml(results, baseName, cluster) { - function xmlEscape(s) { - return s.replace(/[<>&"]/g, function(c) { - return "&" + { - "<": "lt", - ">": "gt", - "&": "amp", - "\"": "quot" - }[c] + ";"; - }); - } - - function buildXml() { - let xml = ["\n"]; - - xml.text = function(s) { - Array.prototype.push.call(this, s); - return this; - }; - - xml.elem = function(tagName, attrs, close) { - this.text("<").text(tagName); - attrs = attrs || {}; - - for (let a in attrs) { - if (attrs.hasOwnProperty(a)) { - this.text(" ").text(a).text("=\"") - .text(xmlEscape(String(attrs[a]))).text("\""); - } - } - - if (close) { - this.text("/"); - } - - this.text(">\n"); - - return this; - }; - - return xml; - } - let clprefix = ''; if (cluster) { clprefix = 'CL_'; } + const isSignificant = function(a, b) { + return (internalMembers.indexOf(b) === -1) && a.hasOwnProperty(b); + }; + for (let testrun in results) { - if ((internalMembers.indexOf(testrun) === -1) && (results.hasOwnProperty(testrun))) { + if (isSignificant(results, testrun)) { for (let test in results[testrun]) { - if ((internalMembers.indexOf(test) === -1) && - results[testrun].hasOwnProperty(test) && - !results[testrun][test].hasOwnProperty('skipped')) { + let run = results[test]; + + if (isSignificant(run, test) && !run[test].hasOwnProperty('skipped')) { + const current = run[test]; let xml = buildXml(); let failuresFound = ""; - if (results[testrun][test].hasOwnProperty('failed')) { - failuresFound = results[testrun][test].failed; + if (current.hasOwnProperty('failed')) { + failuresFound = current.failed; } xml.elem("testsuite", { errors: 0, failures: failuresFound, name: clprefix + test, - tests: results[testrun][test].total, - time: results[testrun][test].duration + tests: current.total, + time: current.duration }); - for (let oneTest in results[testrun][test]) { - if (internalMembers.indexOf(oneTest) === -1) { - const result = results[testrun][test][oneTest].status; + for (let oneTestName in current) { + if (isSignificant(current, oneTestName)) { + const oneTest = current[oneTestName]; + const result = oneTest.status || false; const success = (typeof(result) === 'boolean') ? result : false; xml.elem("testcase", { - name: clprefix + oneTest, - time: results[testrun][test][oneTest].duration + name: clprefix + oneTestName, + time: oneTest.duration }, success); if (!success) { xml.elem("failure"); - xml.text('\n'); + xml.text('\n'); xml.elem("/failure"); xml.elem("/testcase"); } } } - if ((!results[testrun][test].status) && - results[testrun][test].hasOwnProperty('message')) { - + if (!current.status) { xml.elem("testcase", { name: 'all tests in ' + clprefix + test, - time: results[testrun][test].duration + time: current.duration }, false); xml.elem("failure"); - xml.text('\n'); + xml.text('\n'); xml.elem("/failure"); xml.elem("/testcase"); } @@ -130,6 +142,10 @@ function resultsToXml(results, baseName, cluster) { } } +//////////////////////////////////////////////////////////////////////////////// +/// @brief runs the test using testing.js +//////////////////////////////////////////////////////////////////////////////// + function main(argv) { const test = argv[0]; let options = {}; @@ -153,6 +169,7 @@ function main(argv) { start_pretty_print(); + // run the test and store the result let r = {}; try { @@ -174,15 +191,17 @@ function main(argv) { print(JSON.stringify(r)); } + _.defaults(r, { + all_ok: false, + crashed: true + }); + // whether or not there was an error - fs.write("out/UNITTEST_RESULT_EXECUTIVE_SUMMARY.json", JSON.stringify(r.all_ok)); + fs.write("out/UNITTEST_RESULT_EXECUTIVE_SUMMARY.json", String(r.all_ok)); if (options.writeXmlReport) { - fs.write("out/UNITTEST_RESULT.json", JSON.stringify(r)); - - // should be renamed to UNITTEST_RESULT_CRASHED, because that's what - // it actually contains - fs.write("out/UNITTEST_RESULT_SUMMARY.txt", JSON.stringify(!r.crashed)); + fs.write("out/UNITTEST_RESULT.json", inspect(r)); + fs.write("out/UNITTEST_RESULT_CRASHED.txt", String(r.crashed)); try { resultsToXml(r, From 94ffc16e15570362520d0dcd79eec8bd7d358d75 Mon Sep 17 00:00:00 2001 From: Jan Steemann Date: Tue, 2 Feb 2016 13:08:01 +0100 Subject: [PATCH 3/6] always clean up --- js/server/tests/shell/shell-hash-index-failures.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/js/server/tests/shell/shell-hash-index-failures.js b/js/server/tests/shell/shell-hash-index-failures.js index 3f676fc107..aa32f961a3 100644 --- a/js/server/tests/shell/shell-hash-index-failures.js +++ b/js/server/tests/shell/shell-hash-index-failures.js @@ -130,6 +130,7 @@ function HashIndexMultiFailuresSuite () { //////////////////////////////////////////////////////////////////////////////// setUp : function () { + internal.debugClearFailAt(); internal.db._drop(cn); collection = internal.db._create(cn); collection.ensureHashIndex("a"); @@ -140,8 +141,8 @@ function HashIndexMultiFailuresSuite () { //////////////////////////////////////////////////////////////////////////////// tearDown : function () { - internal.db._drop(cn); internal.debugClearFailAt(); + internal.db._drop(cn); }, //////////////////////////////////////////////////////////////////////////////// From 48f1ce865b6ed2953f1cc033d57d8615fac46234 Mon Sep 17 00:00:00 2001 From: Jan Steemann Date: Tue, 2 Feb 2016 14:01:26 +0100 Subject: [PATCH 4/6] don't swallow detailed return codes --- arangod/RestHandler/RestVocbaseBaseHandler.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/arangod/RestHandler/RestVocbaseBaseHandler.cpp b/arangod/RestHandler/RestVocbaseBaseHandler.cpp index 7f811bb7d0..b8a378cbb2 100644 --- a/arangod/RestHandler/RestVocbaseBaseHandler.cpp +++ b/arangod/RestHandler/RestVocbaseBaseHandler.cpp @@ -394,7 +394,7 @@ void RestVocbaseBaseHandler::generateTransactionError( case TRI_ERROR_ARANGO_READ_ONLY: generateError(HttpResponse::FORBIDDEN, res, "collection is read-only"); return; - + case TRI_ERROR_ARANGO_UNIQUE_CONSTRAINT_VIOLATED: generateError(HttpResponse::CONFLICT, res, "cannot create document, unique constraint violated"); @@ -445,6 +445,22 @@ void RestVocbaseBaseHandler::generateTransactionError( generateError(HttpResponse::NOT_IMPLEMENTED, res); return; } + + case TRI_ERROR_FORBIDDEN: { + generateError(HttpResponse::FORBIDDEN, res); + return; + } + + case TRI_ERROR_OUT_OF_MEMORY: + case TRI_ERROR_LOCK_TIMEOUT: + case TRI_ERROR_AID_NOT_FOUND: + case TRI_ERROR_DEBUG: + case TRI_ERROR_LEGEND_NOT_IN_WAL_FILE: + case TRI_ERROR_LOCKED: + case TRI_ERROR_DEADLOCK: { + generateError(HttpResponse::SERVER_ERROR, res); + return; + } default: generateError(HttpResponse::SERVER_ERROR, TRI_ERROR_INTERNAL, From 5eb9687e213de166a6138934f49ca01176048881 Mon Sep 17 00:00:00 2001 From: Jan Steemann Date: Tue, 2 Feb 2016 14:02:28 +0100 Subject: [PATCH 5/6] turn off deadlock detection in cluster --- arangod/RestServer/ArangoServer.cpp | 7 +++++ arangod/V8Server/v8-vocbase.cpp | 2 ++ arangod/VocBase/server.cpp | 17 ++++++++++ arangod/VocBase/server.h | 7 +++++ arangod/VocBase/vocbase.cpp | 1 + lib/Basics/DeadlockDetector.h | 48 ++++++++++++++++++++++++++++- 6 files changed, 81 insertions(+), 1 deletion(-) diff --git a/arangod/RestServer/ArangoServer.cpp b/arangod/RestServer/ArangoServer.cpp index 6dd0abec38..a21c173b81 100644 --- a/arangod/RestServer/ArangoServer.cpp +++ b/arangod/RestServer/ArangoServer.cpp @@ -1168,6 +1168,13 @@ int ArangoServer::startupServer() { } } + + // active deadlock detection in case we're not running in cluster mode + if (!arangodb::ServerState::instance()->isRunningInCluster()) { + TRI_EnableDeadlockDetectionDatabasesServer(_server); + } + + // ............................................................................. // start the work monitor // ............................................................................. diff --git a/arangod/V8Server/v8-vocbase.cpp b/arangod/V8Server/v8-vocbase.cpp index 30ae172e8e..5c2eb1ddbb 100644 --- a/arangod/V8Server/v8-vocbase.cpp +++ b/arangod/V8Server/v8-vocbase.cpp @@ -3362,6 +3362,8 @@ static void JS_CreateDatabase(v8::FunctionCallbackInfo const& args) { TRI_ASSERT(database != nullptr); + database->_deadlockDetector.enabled(!arangodb::ServerState::instance()->isRunningInCluster()); + // copy users into context if (args.Length() >= 3 && args[2]->IsArray()) { v8::Handle users = v8::Object::New(isolate); diff --git a/arangod/VocBase/server.cpp b/arangod/VocBase/server.cpp index e54e29a106..3ca646143f 100644 --- a/arangod/VocBase/server.cpp +++ b/arangod/VocBase/server.cpp @@ -1693,6 +1693,23 @@ int TRI_CreateDatabaseServer(TRI_server_t* server, TRI_voc_tick_t databaseId, return res; } +//////////////////////////////////////////////////////////////////////////////// +/// @brief activates or deactivates deadlock detection in all existing +/// databases +//////////////////////////////////////////////////////////////////////////////// + +void TRI_EnableDeadlockDetectionDatabasesServer(TRI_server_t* server) { + auto unuser(server->_databasesProtector.use()); + auto theLists = server->_databasesLists.load(); + + for (auto& p : theLists->_databases) { + TRI_vocbase_t* vocbase = p.second; + TRI_ASSERT(vocbase != nullptr); + + vocbase->_deadlockDetector.enabled(true); + } +} + //////////////////////////////////////////////////////////////////////////////// /// @brief get the ids of all local coordinator databases /// the caller is responsible for freeing the result diff --git a/arangod/VocBase/server.h b/arangod/VocBase/server.h index 4d69f6ec51..db0a62abe9 100644 --- a/arangod/VocBase/server.h +++ b/arangod/VocBase/server.h @@ -153,6 +153,13 @@ int TRI_CreateDatabaseServer(TRI_server_t*, TRI_voc_tick_t, char const*, TRI_vocbase_defaults_t const*, TRI_vocbase_t**, bool); +//////////////////////////////////////////////////////////////////////////////// +/// @brief activates or deactivates deadlock detection in all existing +/// databases +//////////////////////////////////////////////////////////////////////////////// + +void TRI_EnableDeadlockDetectionDatabasesServer(TRI_server_t*); + //////////////////////////////////////////////////////////////////////////////// /// @brief get the ids of all local coordinator databases /// the caller is responsible for freeing the result diff --git a/arangod/VocBase/vocbase.cpp b/arangod/VocBase/vocbase.cpp index fa06e6fb6f..28d62b9784 100644 --- a/arangod/VocBase/vocbase.cpp +++ b/arangod/VocBase/vocbase.cpp @@ -2349,6 +2349,7 @@ TRI_vocbase_t::TRI_vocbase_t(TRI_server_t* server, TRI_vocbase_type_e type, _type(type), _refCount(0), _server(server), + _deadlockDetector(false), _userStructures(nullptr), _queries(nullptr), _cursorRepository(nullptr), diff --git a/lib/Basics/DeadlockDetector.h b/lib/Basics/DeadlockDetector.h index 4630fe9341..f46e4047db 100644 --- a/lib/Basics/DeadlockDetector.h +++ b/lib/Basics/DeadlockDetector.h @@ -35,7 +35,7 @@ namespace basics { template class DeadlockDetector { public: - DeadlockDetector() = default; + explicit DeadlockDetector(bool enabled) : _enabled(enabled) {}; ~DeadlockDetector() = default; DeadlockDetector(DeadlockDetector const&) = delete; @@ -105,12 +105,34 @@ class DeadlockDetector { void unsetWriter(T const* value) { unsetActive(value, true); } + //////////////////////////////////////////////////////////////////////////////// + /// @brief enable / disable + //////////////////////////////////////////////////////////////////////////////// + + void enabled(bool value) { + MUTEX_LOCKER(mutexLocker, _lock); + _enabled = value; + } + + //////////////////////////////////////////////////////////////////////////////// + /// @brief return the enabled status + //////////////////////////////////////////////////////////////////////////////// + + bool enabled() { + MUTEX_LOCKER(mutexLocker, _lock); + return _enabled; + } + private: //////////////////////////////////////////////////////////////////////////////// /// @brief add a thread to the list of blocked threads //////////////////////////////////////////////////////////////////////////////// int detectDeadlock(T const* value, TRI_tid_t tid, bool isWrite) const { + if (!_enabled) { + return TRI_ERROR_NO_ERROR; + } + struct StackValue { StackValue(T const* value, TRI_tid_t tid, bool isWrite) : value(value), tid(tid), isWrite(isWrite) {} @@ -189,6 +211,10 @@ class DeadlockDetector { MUTEX_LOCKER(mutexLocker, _lock); + if (!_enabled) { + return TRI_ERROR_NO_ERROR; + } + auto it = _blocked.find(tid); if (it != _blocked.end()) { @@ -223,6 +249,10 @@ class DeadlockDetector { MUTEX_LOCKER(mutexLocker, _lock); + if (!_enabled) { + return; + } + _blocked.erase(tid); } @@ -234,6 +264,11 @@ class DeadlockDetector { auto tid = TRI_CurrentThreadId(); MUTEX_LOCKER(mutexLocker, _lock); + + if (!_enabled) { + return; + } + auto it = _active.find(value); if (it == _active.end()) { @@ -266,6 +301,11 @@ class DeadlockDetector { auto tid = TRI_CurrentThreadId(); MUTEX_LOCKER(mutexLocker, _lock); + + if (!_enabled) { + return; + } + auto it = _active.find(value); if (it == _active.end()) { @@ -303,6 +343,12 @@ class DeadlockDetector { std::unordered_map, bool>> _active; + + //////////////////////////////////////////////////////////////////////////////// + /// @brief whether or not the detector is enabled + //////////////////////////////////////////////////////////////////////////////// + + bool _enabled; }; } // namespace arangodb::basics From e9dbd6f648d19694bd80313f238b95d921a11bcd Mon Sep 17 00:00:00 2001 From: Frank Celler Date: Tue, 2 Feb 2016 14:45:08 +0100 Subject: [PATCH 6/6] fixed test for significant attribute --- UnitTests/unittest.js | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/UnitTests/unittest.js b/UnitTests/unittest.js index 27dc44fab7..015c938dfd 100644 --- a/UnitTests/unittest.js +++ b/UnitTests/unittest.js @@ -73,13 +73,17 @@ function resultsToXml(results, baseName, cluster) { return (internalMembers.indexOf(b) === -1) && a.hasOwnProperty(b); }; - for (let testrun in results) { - if (isSignificant(results, testrun)) { - for (let test in results[testrun]) { - let run = results[test]; + for (let resultName in results) { + if (isSignificant(results, resultName)) { + let run = results[resultName]; - if (isSignificant(run, test) && !run[test].hasOwnProperty('skipped')) { - const current = run[test]; + for (let runName in run) { + if (isSignificant(run, runName)) { + const current = run[runName]; + + if (current.skipped) { + continue; + } let xml = buildXml(); let failuresFound = ""; @@ -91,7 +95,7 @@ function resultsToXml(results, baseName, cluster) { xml.elem("testsuite", { errors: 0, failures: failuresFound, - name: clprefix + test, + name: clprefix + runName, tests: current.total, time: current.duration }); @@ -118,7 +122,7 @@ function resultsToXml(results, baseName, cluster) { if (!current.status) { xml.elem("testcase", { - name: 'all tests in ' + clprefix + test, + name: 'all tests in ' + clprefix + runName, time: current.duration }, false); @@ -133,7 +137,7 @@ function resultsToXml(results, baseName, cluster) { xml.elem("/testsuite"); const fn = makePathGeneric(baseName + clprefix + - testrun + '_' + test + ".xml").join('_'); + resultName + '_' + runName + ".xml").join('_'); fs.write("out/" + fn, xml.join("")); }