9 #ifndef LIBPMEMOBJ_CPP_TRANSACTION_HPP 10 #define LIBPMEMOBJ_CPP_TRANSACTION_HPP 20 #include <libpmemobj/tx_base.h> 33 static constexpr
bool value = LIBPMEMOBJ_CPP_IS_TRIVIALLY_COPYABLE(T);
99 template <
typename... L>
104 if (pmemobj_tx_stage() == TX_STAGE_NONE) {
105 ret = pmemobj_tx_begin(pop.
handle(),
nullptr,
107 transaction::c_callback,
108 nullptr, TX_PARAM_NONE);
110 ret = pmemobj_tx_begin(pop.
handle(),
nullptr,
116 "failed to start transaction")
117 .with_pmemobj_errormsg();
119 auto err = add_lock(locks...);
122 pmemobj_tx_abort(EINVAL);
123 (void)pmemobj_tx_end();
125 "failed to add lock")
126 .with_pmemobj_errormsg();
140 if (pmemobj_tx_stage() == TX_STAGE_WORK)
141 pmemobj_tx_abort(ECANCELED);
143 (void)pmemobj_tx_end();
171 #if __cpp_lib_uncaught_exceptions || _MSC_VER >= 1900 210 template <
typename... L>
212 : tx_worker(pop, locks...)
229 if (exceptions.new_uncaught_exception())
233 if (pmemobj_tx_stage() == TX_STAGE_WORK)
236 else if (pmemobj_tx_stage() == TX_STAGE_ONABORT ||
237 (pmemobj_tx_stage() == TX_STAGE_FINALLY &&
238 pmemobj_tx_errno() != 0))
240 "Transaction aborted");
276 : count(
std::uncaught_exceptions())
290 return std::uncaught_exceptions() > this->count;
334 if (pmemobj_tx_stage() != TX_STAGE_WORK)
337 pmemobj_tx_abort(err);
339 std::to_string(err));
355 if (pmemobj_tx_stage() != TX_STAGE_WORK)
364 return pmemobj_tx_errno();
367 POBJ_CPP_DEPRECATED
static int 368 get_last_tx_error() noexcept
370 return transaction::error();
404 template <
typename... Locks>
410 if (pmemobj_tx_stage() == TX_STAGE_NONE) {
411 ret = pmemobj_tx_begin(pool.
handle(),
nullptr,
413 transaction::c_callback,
nullptr,
416 ret = pmemobj_tx_begin(pool.
handle(),
nullptr,
422 "failed to start transaction")
423 .with_pmemobj_errormsg();
425 auto err = add_lock(locks...);
428 pmemobj_tx_abort(err);
429 (void)pmemobj_tx_end();
431 "failed to add a lock to the transaction")
432 .with_pmemobj_errormsg();
438 (void)pmemobj_tx_end();
442 if (pmemobj_tx_stage() == TX_STAGE_WORK)
443 pmemobj_tx_abort(ECANCELED);
446 (void)pmemobj_tx_end();
450 auto stage = pmemobj_tx_stage();
452 if (
stage == TX_STAGE_WORK) {
454 }
else if (
stage == TX_STAGE_ONABORT) {
455 (void)pmemobj_tx_end();
457 }
else if (
stage == TX_STAGE_NONE) {
459 "transaction ended prematurely");
462 (void)pmemobj_tx_end();
465 template <
typename... Locks>
466 POBJ_CPP_DEPRECATED
static void 467 exec_tx(
pool_base &pool, std::function<
void()> tx, Locks &... locks)
469 transaction::run(pool, tx, locks...);
492 template <
typename T,
493 typename std::enable_if<detail::can_do_snapshot<T>::value,
494 T>::type * =
nullptr>
498 if (TX_STAGE_WORK != pmemobj_tx_stage())
500 "wrong stage for taking a snapshot.");
502 if (pmemobj_tx_add_range_direct(addr,
sizeof(*addr) * num)) {
505 "Could not take a snapshot of given memory range.")
506 .with_pmemobj_errormsg();
509 "Could not take a snapshot of given memory range.")
510 .with_pmemobj_errormsg();
519 work = TX_STAGE_WORK,
520 oncommit = TX_STAGE_ONCOMMIT,
521 onabort = TX_STAGE_ONABORT,
523 finally = TX_STAGE_FINALLY,
542 if (pmemobj_tx_stage() != TX_STAGE_WORK)
544 "register_callback must be called during a transaction");
546 get_tx_data()->callbacks[
static_cast<size_t>(stg)].push_back(
563 template <
typename L,
typename... Locks>
568 pmemobj_tx_lock(lock.lock_type(), lock.native_handle());
573 return add_lock(locks...);
585 using callbacks_list_type = std::vector<std::function<void()>>;
586 using callbacks_map_type =
587 std::array<callbacks_list_type, MAX_TX_STAGE>;
594 c_callback(PMEMobjpool *pop,
enum pobj_tx_stage obj_stage,
void *arg)
601 if (obj_stage == TX_STAGE_NONE)
604 auto *data =
static_cast<tx_data *
>(pmemobj_tx_get_user_data());
608 for (
auto &cb : data->callbacks[obj_stage])
615 if (obj_stage == TX_STAGE_FINALLY) {
617 pmemobj_tx_set_user_data(NULL);
626 callbacks_map_type callbacks;
636 auto *data =
static_cast<tx_data *
>(pmemobj_tx_get_user_data());
637 if (data ==
nullptr) {
639 pmemobj_tx_set_user_data(data);
int count
The number of active exceptions.
Definition: transaction.hpp:297
static int add_lock() noexcept
Method ending the recursive algorithm.
Definition: transaction.hpp:580
The non-template pool base class.
Definition: pool.hpp:46
Internal class for counting active exceptions.
Definition: transaction.hpp:267
~manual() noexcept
Destructor.
Definition: transaction.hpp:137
~automatic() noexcept(false)
Destructor.
Definition: transaction.hpp:226
C++ transaction handler class.
Definition: transaction.hpp:64
static void c_callback(PMEMobjpool *pop, enum pobj_tx_stage obj_stage, void *arg)
C-style function which is passed as callback to pmemobj_begin.
Definition: transaction.hpp:594
Custom transaction error class.
Definition: pexceptions.hpp:168
Definition: concurrent_hash_map.hpp:42
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 ...
Definition: transaction.hpp:496
C++ manual scope transaction class.
Definition: transaction.hpp:84
PMEMobj pool class.
Definition: persistent_ptr.hpp:30
PMEMobjpool * handle() noexcept
Gets the C style handle to the pool.
Definition: pool.hpp:398
stage
Possible stages of a transaction, for every stage one or more callbacks can be registered.
Definition: transaction.hpp:518
manual(obj::pool_base &pop, L &... locks)
RAII constructor with pmem resident locks.
Definition: transaction.hpp:100
Commonly used functionality.
static void commit()
Manually commit a transaction.
Definition: transaction.hpp:353
static tx_data * get_tx_data()
Gets tx user data from pmemobj or creates it if this is a first call to this function inside a transa...
Definition: transaction.hpp:634
C++ automatic scope transaction class.
Definition: transaction.hpp:191
Custom transaction error class.
Definition: pexceptions.hpp:63
Custom out of memory error class.
Definition: pexceptions.hpp:119
This data is stored along with the pmemobj transaction data using pmemobj_tx_set_data().
Definition: transaction.hpp:625
static int add_lock(L &lock, Locks &... locks) noexcept
Recursively add locks to the active transaction.
Definition: transaction.hpp:565
bool new_uncaught_exception()
Notifies is a new exception is being handled.
Definition: transaction.hpp:288
automatic(obj::pool_base &pop, L &... locks)
RAII constructor with pmem resident locks.
Definition: transaction.hpp:211
uncaught_exception_counter()
Default constructor.
Definition: transaction.hpp:275
Resides on pmem class.
Definition: p.hpp:35
Custom transaction error class.
Definition: pexceptions.hpp:158
Persistent memory namespace.
Definition: allocation_flag.hpp:14
static void register_callback(stage stg, std::function< void()> cb)
Registers callback to be called on specified stage for the transaction.
Definition: transaction.hpp:540
static void run(pool_base &pool, std::function< void()> tx, Locks &... locks)
Execute a closure-like transaction and lock locks.
Definition: transaction.hpp:406
A structure that checks if it is possible to snapshot the specified memory.
Definition: transaction.hpp:32