diff options
-rw-r--r-- | include/erebos/service.h | 3 | ||||
-rw-r--r-- | src/network.cpp | 6 | ||||
-rw-r--r-- | src/pairing.cpp | 12 | ||||
-rw-r--r-- | src/service.cpp | 11 | ||||
-rw-r--r-- | src/service.h | 1 |
5 files changed, 29 insertions, 4 deletions
diff --git a/include/erebos/service.h b/include/erebos/service.h index ba06495..7a9a366 100644 --- a/include/erebos/service.h +++ b/include/erebos/service.h @@ -26,6 +26,9 @@ public: const Stored<LocalState> & local() const; void local(const LocalState &); + void afterCommit(function<void()>); + void runAfterCommitHooks() const; + private: std::unique_ptr<Priv> p; }; diff --git a/src/network.cpp b/src/network.cpp index 4e802f9..8d318f7 100644 --- a/src/network.cpp +++ b/src/network.cpp @@ -703,8 +703,10 @@ void Server::Peer::updateService(ReplyBuilder & reply) for (auto & x : serviceQueue) { if (auto ref = std::get<1>(x)->check(reply)) { if (lpeer) { + Service::Context ctx { nullptr }; + server.localHead.update([&] (const Stored<LocalState> & local) { - Service::Context ctx(new Service::Context::Priv { + ctx = Service::Context(new Service::Context::Priv { .ref = *ref, .peer = erebos::Peer(lpeer), .local = local, @@ -719,6 +721,8 @@ void Server::Peer::updateService(ReplyBuilder & reply) return ctx.local(); }); + + ctx.runAfterCommitHooks(); } } else { next.push_back(std::move(x)); diff --git a/src/pairing.cpp b/src/pairing.cpp index f25cb5c..c22a7af 100644 --- a/src/pairing.cpp +++ b/src/pairing.cpp @@ -147,7 +147,9 @@ void PairingServiceBase::handle(Context & ctx) requestNonceFailedHook(ctx.peer()); if (state->phase < StatePhase::PairingDone) { state->phase = StatePhase::PairingFailed; - state->outcome.set_value(Outcome::NonceMismatch); + ctx.afterCommit([&]() { + state->outcome.set_value(Outcome::NonceMismatch); + }); } return; } @@ -166,7 +168,9 @@ void PairingServiceBase::handle(Context & ctx) else if (auto reject = rec->item("reject").asText()) { if (state->phase < StatePhase::PairingDone) { state->phase = StatePhase::PairingFailed; - state->outcome.set_value(Outcome::PeerRejected); + ctx.afterCommit([&]() { + state->outcome.set_value(Outcome::PeerRejected); + }); } } @@ -174,7 +178,9 @@ void PairingServiceBase::handle(Context & ctx) if (state->phase == StatePhase::OurRequestReady) { handlePairingResult(ctx); state->phase = StatePhase::PairingDone; - state->outcome.set_value(Outcome::Success); + ctx.afterCommit([&]() { + state->outcome.set_value(Outcome::Success); + }); } else { result = ctx.ref(); } diff --git a/src/service.cpp b/src/service.cpp index 14ff665..397bebd 100644 --- a/src/service.cpp +++ b/src/service.cpp @@ -34,6 +34,17 @@ void Service::Context::local(const LocalState & ls) p->local = p->local.ref().storage().store(ls); } +void Service::Context::afterCommit(function<void()> hook) +{ + p->afterCommit.push_back(move(hook)); +} + +void Service::Context::runAfterCommitHooks() const +{ + for (const auto & hook : p->afterCommit) + hook(); +} + void Service::serverStarted(const class Server &) { } diff --git a/src/service.h b/src/service.h index 5296bb3..dada1fb 100644 --- a/src/service.h +++ b/src/service.h @@ -10,6 +10,7 @@ struct Service::Context::Priv Ref ref; Peer peer; Stored<LocalState> local; + vector<function<void()>> afterCommit {}; }; } |