libpmemobj-cpp icon indicating copy to clipboard operation
libpmemobj-cpp copied to clipboard

Handle free()/destruction failure in containers dtors

Open igchor opened this issue 6 years ago • 1 comments

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).

igchor avatar Oct 04 '19 14:10 igchor

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

igchor avatar Jan 23 '20 11:01 igchor