From 9b2de5f4fcef8d77873bbda7db7f6e6d4f596154 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Sat, 30 Mar 2019 14:35:07 -0700 Subject: [PATCH] ircd::json::stack: Add conditional exception rollback toggle. --- include/ircd/json/stack.h | 8 ++++++-- ircd/json.cc | 9 +++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/include/ircd/json/stack.h b/include/ircd/json/stack.h index c51c7d4a7..56bfe9778 100644 --- a/include/ircd/json/stack.h +++ b/include/ircd/json/stack.h @@ -248,7 +248,7 @@ struct ircd::json::stack::const_chase /// rollback() pitfall. /// /// - Destruction under an exception is equivalent to a decommit() and will -/// perform a rollback(). +/// perform a rollback() if exception_rollback is set. /// /// Flushes are avoided under the scope of a checkpoint, but they are still /// forced if the json::stack buffer fills up. In this case all active @@ -261,6 +261,7 @@ struct ircd::json::stack::checkpoint size_t point {0}; size_t vc {0}; bool committed {true}; + bool exception_rollback {true}; public: bool committing() const; ///< When false, destructor will rollback() @@ -268,7 +269,10 @@ struct ircd::json::stack::checkpoint bool decommit(); ///< Sets committing() to false. bool rollback(); ///< Performs rollback of buffer. - checkpoint(stack &s, const bool &committed = true); + checkpoint(stack &s, + const bool &committed = true, + const bool &exception_rollback = true); + checkpoint(checkpoint &&) = delete; checkpoint(const checkpoint &) = delete; ~checkpoint() noexcept; diff --git a/ircd/json.cc b/ircd/json.cc index 723387643..e9050bfef 100644 --- a/ircd/json.cc +++ b/ircd/json.cc @@ -1459,7 +1459,8 @@ ircd::json::stack::member::_post_append() // ircd::json::stack::checkpoint::checkpoint(stack &s, - const bool &committed) + const bool &committed, + const bool &exception_rollback) :s{&s} ,pc{s.cp} ,point @@ -1486,6 +1487,10 @@ ircd::json::stack::checkpoint::checkpoint(stack &s, { committed } +,exception_rollback +{ + exception_rollback +} { s.cp = this; } @@ -1496,7 +1501,7 @@ noexcept if(!s) return; - if(std::uncaught_exceptions()) + if(std::uncaught_exceptions() && exception_rollback) decommit(); if(!committing())