libpmemobj-cpp
libpmemobj-cpp copied to clipboard
Handle free()/destruction failure in containers dtors
One solution is to call free_data() in delete_persistent method. This will allow to propagate exception and not abort application (if throwed inside destructor). All containers should implement this method.
Another solution is to to use pmdk add_buffer feature to reserve space for free(). The problem is with non-trivial types because we need to call destructors for those. (For trivial types we can skip destruction).
The main problem is that exception can be thrown inside of a destructor (because of tx abort). If a destructor is called from within a transaction (always true for delete_peristent) we could just catch any exception and ignore it:
~dtor()
{
if (pmemobj_tx_stage() == TX_STAGE_WORK) {
try {
delete_persistent<>();
} catch (...) {
if (pmemobj_tx_stage() == TX_STAGE_ABORT) {} // ignore, outer transaction will see the state and also throw an exception
else pmemobj_tx_abort();
}
} else {
transaction::run([]{ delete_persistent<>();}); // XXX: should this still cause abort?
}
}
All this code could be exposed as some generic API.
Some things to keep in mind:
- support for no_abort
- problem with https://github.com/pmem/libpmemobj-cpp/issues/516