diff --git a/fdbserver/tester.actor.cpp b/fdbserver/tester.actor.cpp index f9c884e2f9..b413f20fc2 100644 --- a/fdbserver/tester.actor.cpp +++ b/fdbserver/tester.actor.cpp @@ -256,18 +256,14 @@ Standalone> checkAllOptionsConsumed(VectorRef workloads; + std::vector> workloads; CompoundWorkload(WorkloadContext& wcx) : TestWorkload(wcx) {} - CompoundWorkload* add(TestWorkload* w) { - workloads.push_back(w); + CompoundWorkload* add(Reference&& w) { + workloads.push_back(std::move(w)); return this; } - ~CompoundWorkload() override { - for (int w = 0; w < workloads.size(); w++) - delete workloads[w]; - } std::string description() const override { std::string d; for (int w = 0; w < workloads.size(); w++) @@ -345,9 +341,9 @@ struct CompoundWorkload : TestWorkload { } }; -TestWorkload* getWorkloadIface(WorkloadRequest work, - VectorRef options, - Reference const> dbInfo) { +Reference getWorkloadIface(WorkloadRequest work, + VectorRef options, + Reference const> dbInfo) { Value testName = getOption(options, LiteralStringRef("testName"), LiteralStringRef("no-test-specified")); WorkloadContext wcx; wcx.clientId = work.clientId; @@ -356,7 +352,7 @@ TestWorkload* getWorkloadIface(WorkloadRequest work, wcx.options = options; wcx.sharedRandomNumber = work.sharedRandomNumber; - TestWorkload* workload = IWorkloadFactory::create(testName.toString(), wcx); + auto workload = IWorkloadFactory::create(testName.toString(), wcx); auto unconsumedOptions = checkAllOptionsConsumed(workload ? workload->options : VectorRef()); if (!workload || unconsumedOptions.size()) { @@ -375,14 +371,13 @@ TestWorkload* getWorkloadIface(WorkloadRequest work, " '%s' = '%s'\n", unconsumedOptions[i].key.toString().c_str(), unconsumedOptions[i].value.toString().c_str()); - delete workload; } throw test_specification_invalid(); } return workload; } -TestWorkload* getWorkloadIface(WorkloadRequest work, Reference const> dbInfo) { +Reference getWorkloadIface(WorkloadRequest work, Reference const> dbInfo) { if (work.options.size() < 1) { TraceEvent(SevError, "TestCreationError").detail("Reason", "No options provided"); fprintf(stderr, "ERROR: No options were provided for workload.\n"); @@ -397,10 +392,9 @@ TestWorkload* getWorkloadIface(WorkloadRequest work, Reference(wcx); for (int i = 0; i < work.options.size(); i++) { - TestWorkload* workload = getWorkloadIface(work, work.options[i], dbInfo); - compound->add(workload); + compound->add(getWorkloadIface(work, work.options[i], dbInfo)); } return compound; } @@ -526,9 +520,8 @@ void sendResult(ReplyPromise& reply, Optional> const& result) { ACTOR Future runWorkloadAsync(Database cx, WorkloadInterface workIface, - TestWorkload* workload, + Reference workload, double databasePingDelay) { - state std::unique_ptr delw(workload); state Optional> setupResult; state Optional> startResult; state Optional> checkResult; @@ -654,7 +647,7 @@ ACTOR Future testerServerWorkload(WorkloadRequest work, // add test for "done" ? TraceEvent("WorkloadReceived", workIface.id()).detail("Title", work.title); - TestWorkload* workload = getWorkloadIface(work, dbInfo); + auto workload = getWorkloadIface(work, dbInfo); if (!workload) { TraceEvent("TestCreationError").detail("Reason", "Workload could not be created"); fprintf(stderr, "ERROR: The workload could not be created.\n"); diff --git a/fdbserver/workloads/workloads.actor.h b/fdbserver/workloads/workloads.actor.h index eaa0936cf2..a09f52a605 100644 --- a/fdbserver/workloads/workloads.actor.h +++ b/fdbserver/workloads/workloads.actor.h @@ -57,7 +57,7 @@ struct WorkloadContext { WorkloadContext& operator=(const WorkloadContext&) = delete; }; -struct TestWorkload : NonCopyable, WorkloadContext { +struct TestWorkload : NonCopyable, WorkloadContext, ReferenceCounted { int phases; // Subclasses are expected to also have a constructor with this signature (to work with WorkloadFactory<>): @@ -103,25 +103,25 @@ struct KVWorkload : TestWorkload { Key keyForIndex(uint64_t index, bool absent) const; }; -struct IWorkloadFactory { - static TestWorkload* create(std::string const& name, WorkloadContext const& wcx) { +struct IWorkloadFactory : ReferenceCounted { + static Reference create(std::string const& name, WorkloadContext const& wcx) { auto it = factories().find(name); if (it == factories().end()) - return nullptr; // or throw? + return {}; // or throw? return it->second->create(wcx); } - static std::map& factories() { - static std::map theFactories; + static std::map>& factories() { + static std::map> theFactories; return theFactories; } - virtual TestWorkload* create(WorkloadContext const& wcx) = 0; + virtual Reference create(WorkloadContext const& wcx) = 0; }; template struct WorkloadFactory : IWorkloadFactory { - WorkloadFactory(const char* name) { factories()[name] = this; } - TestWorkload* create(WorkloadContext const& wcx) override { return new WorkloadType(wcx); } + WorkloadFactory(const char* name) { factories()[name] = Reference::addRef(this); } + Reference create(WorkloadContext const& wcx) override { return makeReference(wcx); } }; #define REGISTER_WORKLOAD(classname) WorkloadFactory classname##WorkloadFactory(#classname)