9 #ifndef LIBPMEMOBJ_CPP_TRANSACTION_HPP
10 #define LIBPMEMOBJ_CPP_TRANSACTION_HPP
20 #include <libpmemobj/tx_base.h>
27 #ifndef LIBPMEMOBJ_CPP_FLAT_TX_USE_FAILURE_RETURN
28 #define LIBPMEMOBJ_CPP_FLAT_TX_USE_FAILURE_RETURN true
42 static constexpr
bool value = LIBPMEMOBJ_CPP_IS_TRIVIALLY_COPYABLE(T);
48 template <
bool is_flat>
66 template <
typename... L>
71 nested = pmemobj_tx_stage() == TX_STAGE_WORK;
74 ret = pmemobj_tx_begin(pop.
handle(),
nullptr,
76 }
else if (pmemobj_tx_stage() == TX_STAGE_NONE) {
77 ret = pmemobj_tx_begin(
78 pop.
handle(),
nullptr, TX_PARAM_CB,
79 transaction_base::c_callback,
nullptr,
83 "Cannot start transaction in stage different than WORK or NONE");
89 "failed to start transaction");
91 auto err = add_lock(locks...);
94 pmemobj_tx_abort(EINVAL);
95 (void)pmemobj_tx_end();
98 "failed to add lock");
101 set_failure_behavior();
114 if (pmemobj_tx_stage() == TX_STAGE_WORK) {
115 if (is_flat && nested)
118 pmemobj_tx_abort(ECANCELED);
121 (void)pmemobj_tx_end();
127 manual(
const manual &p) =
delete;
132 manual(
const manual &&p) =
delete;
137 manual &operator=(
const manual &p) =
delete;
142 manual &operator=(manual &&p) =
delete;
145 template <
bool cnd = is_flat
147 typename std::enable_if<cnd>::type
148 set_failure_behavior()
150 pmemobj_tx_set_failure_behavior(POBJ_TX_FAILURE_RETURN);
153 template <
bool cnd = is_flat
155 typename std::enable_if<!cnd>::type
156 set_failure_behavior()
167 #if __cpp_lib_uncaught_exceptions || _MSC_VER >= 1900
187 template <
typename... L>
189 : tx_worker(pop, locks...)
203 ~automatic() noexcept(
false)
206 if (exceptions.new_uncaught_exception())
210 if (pmemobj_tx_stage() == TX_STAGE_WORK)
213 else if (pmemobj_tx_stage() == TX_STAGE_ONABORT ||
214 (pmemobj_tx_stage() == TX_STAGE_FINALLY &&
215 pmemobj_tx_errno() != 0))
217 "Transaction aborted");
223 automatic(
const automatic &p) =
delete;
228 automatic(
const automatic &&p) =
delete;
233 automatic &operator=(
const automatic &p) =
delete;
238 automatic &operator=(automatic &&p) =
delete;
244 class uncaught_exception_counter {
252 uncaught_exception_counter()
253 : count(std::uncaught_exceptions())
265 new_uncaught_exception()
267 return std::uncaught_exceptions() > this->count;
311 if (pmemobj_tx_stage() != TX_STAGE_WORK)
314 pmemobj_tx_abort(err);
316 std::to_string(err));
332 if (pmemobj_tx_stage() != TX_STAGE_WORK)
341 return pmemobj_tx_errno();
344 POBJ_CPP_DEPRECATED
static int
345 get_last_tx_error() noexcept
385 template <
typename... Locks>
389 manual worker(pool, locks...);
393 auto stage = pmemobj_tx_stage();
395 if (
stage == TX_STAGE_WORK) {
397 }
else if (
stage == TX_STAGE_ONABORT) {
399 }
else if (
stage == TX_STAGE_NONE) {
401 "transaction ended prematurely");
405 template <
typename... Locks>
406 POBJ_CPP_DEPRECATED
static void
410 run(pool, tx, locks...);
433 template <
typename T,
434 typename std::enable_if<detail::can_do_snapshot<T>::value,
435 T>::type * =
nullptr>
439 if (TX_STAGE_WORK != pmemobj_tx_stage())
441 "wrong stage for taking a snapshot.");
443 if (pmemobj_tx_add_range_direct(addr,
sizeof(*addr) * num)) {
445 "Could not take a snapshot of given memory range.";
466 work = TX_STAGE_WORK,
470 finally = TX_STAGE_FINALLY,
489 if (pmemobj_tx_stage() != TX_STAGE_WORK)
491 "register_callback must be called during a transaction");
493 get_tx_data()->callbacks[
static_cast<size_t>(stg)].push_back(
510 template <
typename L,
typename... Locks>
512 add_lock(L &lock, Locks &... locks) noexcept
515 pmemobj_tx_lock(lock.lock_type(), lock.native_handle());
520 return add_lock(locks...);
532 using callbacks_list_type = std::vector<std::function<void()>>;
533 using callbacks_map_type =
534 std::array<callbacks_list_type, MAX_TX_STAGE>;
541 c_callback(PMEMobjpool *pop,
enum pobj_tx_stage obj_stage,
void *arg)
548 if (obj_stage == TX_STAGE_NONE)
551 auto *data =
static_cast<tx_data *
>(pmemobj_tx_get_user_data());
555 for (
auto &cb : data->callbacks[obj_stage])
562 if (obj_stage == TX_STAGE_FINALLY) {
564 pmemobj_tx_set_user_data(NULL);
573 callbacks_map_type callbacks;
583 auto *data =
static_cast<tx_data *
>(pmemobj_tx_get_user_data());
584 if (data ==
nullptr) {
586 pmemobj_tx_set_user_data(data);
649 #if __cpp_lib_uncaught_exceptions || _MSC_VER >= 1900
674 template <
typename... Locks>
751 #if __cpp_lib_uncaught_exceptions || _MSC_VER >= 1900
808 template <
typename... Locks>
826 #ifdef LIBPMEMOBJ_CPP_USE_FLAT_TRANSACTION
Common functionality for basic_transaction and flat_transaction.
Definition: transaction.hpp:49
static void commit()
Manually commit a transaction.
Definition: transaction.hpp:330
stage
Possible stages of a transaction.
Definition: transaction.hpp:465
@ oncommit
successfully committed
@ onabort
tx_begin failed or transaction aborted
@ work
transaction in progress
~transaction_base() noexcept=delete
Default destructor.
static void snapshot(const T *addr, size_t num=1)
Takes a “snapshot” of given elements of type T number (1 by default), located at the given address pt...
Definition: transaction.hpp:437
static void register_callback(stage stg, std::function< void()> cb)
Registers callback to be called on specified stage for the transaction.
Definition: transaction.hpp:487
static void run(obj::pool_base &pool, std::function< void()> tx, Locks &... locks)
Execute a closure-like transaction and lock locks.
Definition: transaction.hpp:387
static void abort(int err)
Manually abort the current transaction.
Definition: transaction.hpp:309
Custom transaction error class.
Definition: pexceptions.hpp:178
C++ transaction handler class.
Definition: transaction.hpp:623
~basic_transaction() noexcept=delete
Default destructor.
typename detail::transaction_base< false >::automatic automatic
C++ automatic scope transaction class.
Definition: transaction.hpp:669
static void run(obj::pool_base &pool, std::function< void()> tx, Locks &... locks)
Execute a closure-like transaction and lock locks.
Definition: transaction.hpp:676
typename detail::transaction_base< false >::manual manual
C++ manual scope transaction class.
Definition: transaction.hpp:643
C++ flat transaction handler class.
Definition: transaction.hpp:724
~flat_transaction() noexcept=delete
Default destructor.
typename detail::transaction_base< true >::manual manual
C++ manual scope transaction class.
Definition: transaction.hpp:745
static void run(obj::pool_base &pool, std::function< void()> tx, Locks &... locks)
Execute a closure-like transaction and lock locks.
Definition: transaction.hpp:810
typename detail::transaction_base< true >::automatic automatic
C++ automatic scope transaction class.
Definition: transaction.hpp:771
The non-template pool base class.
Definition: pool.hpp:51
PMEMobjpool * handle() noexcept
Gets the C style handle to the pool.
Definition: pool.hpp:395
PMEMobj pool class.
Definition: pool.hpp:482
Custom transaction error class.
Definition: pexceptions.hpp:109
Custom out of memory error class.
Definition: pexceptions.hpp:144
Custom transaction error class.
Definition: pexceptions.hpp:167
Commonly used functionality.
ExcT exception_with_errormsg(Args &&... args)
Generic error message decorator for pmemobj-based exceptions.
Definition: pexceptions.hpp:69
Persistent memory namespace.
Definition: allocation_flag.hpp:15
A structure that checks if it is possible to snapshot the specified memory.
Definition: transaction.hpp:41
#define LIBPMEMOBJ_CPP_FLAT_TX_USE_FAILURE_RETURN
Definition to enable back the old transaction behavior.
Definition: transaction.hpp:28