Skip to content

Make Borrowable's descructor warn / crash if destructed with outstanding borrows #47

Description

@CodingCanuck

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions