Borrowable's destructor currently hangs until all borrows of the object have been relinquished:
|
// NOTE: currently this implementation of Borrowable does an atomic |
|
// backoff instead of blocking the thread when the destructor waits |
|
// for all borrows to be relinquished. This will be much less |
|
// efficient (and hold up a CPU) if the borrowers take a while to |
|
// relinquish. However, since Borrowable will mostly be used in |
|
// cirumstances where the tally is definitely back to 0 when we wait |
|
// no backoff will occur. For circumstances where Borrowable is being |
|
// used to wait until work is completed consider using a Notification |
|
// to be notified when the work is complete and then Borrowable should |
|
// destruct without any atomic backoff (because any workers/threads |
|
// will have relinquished). |
I'd call this surprising behavior: it's not mentioned in documentation that I can see (e.g. not in the old borrowed_ptr README), and it's sharply different behavior from other standard c++ smart pointers (namely std::unique_ptr, std::shared_ptr, and std::weak_ptr) and boost smart pointers.
Let's print a warning warns if a borrrowable destructor is called without outstanding non-relinquished borrows. A warning would have saved me several days of debugging: I had written buggy code where a borrowable was destructed before its uses were relinquished. I didn't expect incorrect Borrowable use to cause deadlocks, and I wasn't able to diagnose the issue without attaching a debugger.
Better yet, let's make this default behavior and remove the default of atomic backoff. (Atomic backoff feels like an orthogonal feature to a safe alternative to raw pointers: if it's something needed by some use cases, perhaps there could be a WaitingBorrowedPointer or similar that adds this extra backoff functionality in an opt-in fashion that most callers would only use if they have shared / non-simple ownership).
Borrowable's destructor currently hangs until all borrows of the object have been relinquished:
stout/include/stout/borrowed_ptr.h
Lines 26 to 36 in 8dce905
I'd call this surprising behavior: it's not mentioned in documentation that I can see (e.g. not in the old borrowed_ptr README), and it's sharply different behavior from other standard c++ smart pointers (namely
std::unique_ptr,std::shared_ptr, andstd::weak_ptr) and boost smart pointers.Let's print a warning warns if a borrrowable destructor is called without outstanding non-relinquished borrows. A warning would have saved me several days of debugging: I had written buggy code where a borrowable was destructed before its uses were relinquished. I didn't expect incorrect Borrowable use to cause deadlocks, and I wasn't able to diagnose the issue without attaching a debugger.
Better yet, let's make this default behavior and remove the default of atomic backoff. (Atomic backoff feels like an orthogonal feature to a safe alternative to raw pointers: if it's something needed by some use cases, perhaps there could be a WaitingBorrowedPointer or similar that adds this extra backoff functionality in an opt-in fashion that most callers would only use if they have shared / non-simple ownership).