Open igchor opened 5 years ago
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:
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).