Fix issue with movement/consumption tracking in MgFuture and MgPromise

This commit is contained in:
Tyler Neely 2022-07-05 17:36:47 +00:00
parent 29e8d8e72c
commit 28516763b9
3 changed files with 33 additions and 10 deletions
src/io/v3
tests/simulation

View File

@ -125,11 +125,12 @@ class MgFuture {
MgFuture(MgFuture &&old) {
shared_ = std::move(old.shared_);
consumed_or_moved_ = old.consumed_or_moved_;
MG_ASSERT(!old.consumed_or_moved_, "MgFuture moved from after already being moved from or consumed.");
old.consumed_or_moved_ = true;
}
MgFuture &operator=(MgFuture &&old) {
shared_ = std::move(old.shared_);
consumed_or_moved_ = old.consumed_or_moved_;
MG_ASSERT(!old.consumed_or_moved_, "MgFuture moved from after already being moved from or consumed.");
old.consumed_or_moved_ = true;
}
MgFuture(const MgFuture &) = delete;
@ -148,7 +149,7 @@ class MgFuture {
private:
MgFuture(std::shared_ptr<Shared<T>> shared) : shared_(shared) {}
bool consumed_or_moved_;
bool consumed_or_moved_ = false;
std::shared_ptr<Shared<T>> shared_;
};
@ -160,12 +161,12 @@ class MgPromise {
public:
MgPromise(MgPromise &&old) {
shared_ = std::move(old.shared_);
filled_or_moved_ = old.filled_or_moved_;
MG_ASSERT(!old.filled_or_moved_, "MgPromise moved from after already being moved from or filled.");
old.filled_or_moved_ = true;
}
MgPromise &operator=(MgPromise &&old) {
shared_ = std::move(old.shared_);
filled_or_moved_ = old.filled_or_moved_;
MG_ASSERT(!old.filled_or_moved_, "MgPromise moved from after already being moved from or filled.");
old.filled_or_moved_ = true;
}
MgPromise(const MgPromise &) = delete;
@ -186,7 +187,7 @@ class MgPromise {
MgPromise(std::shared_ptr<Shared<T>> shared) : shared_(shared) {}
std::shared_ptr<Shared<T>> shared_;
bool filled_or_moved_;
bool filled_or_moved_ = false;
};
template <typename T>

View File

@ -43,6 +43,8 @@ class SimulatorTransport {
std::function<void()> notifier = [=] { simulator_handle_->NotifySimulator(); };
auto [future, promise] = FuturePromisePairWithNotifier<ResponseResult<Response>>(notifier);
simulator_handle_->SubmitRequest(address, request_id, request, timeout_microseconds, std::move(promise));
return std::move(future);
}

View File

@ -15,17 +15,37 @@
#include "io/v3/future.hpp"
#include "utils/logging.hpp"
void Fill(MgPromise<std::string> promise) { promise.Fill("success"); }
void Fill(MgPromise<std::string> promise_1) { promise_1.Fill("success"); }
void Wait(MgFuture<std::string> future_1, MgPromise<std::string> promise_2) {
std::string result_1 = future_1.Wait();
MG_ASSERT(result_1 == "success");
promise_2.Fill("it worked");
}
int main() {
auto [future, promise] = FuturePromisePair<std::string>();
std::atomic_bool filled = false;
std::jthread t1(Fill, std::move(promise));
std::function<void()> notifier = [&] { filled.store(true, std::memory_order_seq_cst); };
auto [future_1, promise_1] = FuturePromisePairWithNotifier<std::string>(notifier);
auto [future_2, promise_2] = FuturePromisePair<std::string>();
std::jthread t1(Wait, std::move(future_1), std::move(promise_2));
// spin in a loop until the promise signals
// that it is waiting
while (!filled.load(std::memory_order_acquire)) {
std::this_thread::yield();
}
std::jthread t2(Fill, std::move(promise_1));
std::string result = future.Wait();
t1.join();
t2.join();
MG_ASSERT(result == "success");
std::string result_2 = future_2.Wait();
MG_ASSERT(result_2 == "it worked");
return 0;
}