vendredi 8 mai 2015

Why isn't std::condition_variable templated by lock type?

It's useful to have the ability to assert in debug mode, with reasonably small overhead, whether a mutex is locked. Viewing the known options, I've chosen to implement this using an std::mutex subclass due to the low overheads.

The interface of the subclass is a superset of that of std::mutex, and so most things work well with it. E.g., std::unique_lock is templated to utilize any lock type that has a specific interface.

The problem is with std::condition_variable, in particular the wait members, e.g.:

template<class Predicate>
void wait(std::unique_lock<std::mutex> &lock, Predicate pred);

As can be seen, the method requires a very specific unique_lock/mutex combination. Unfortunately, also, the Liskov principle doesn't extend for container<derived> being converted into container<base>.

I don't understand

  1. why this is so?

Even if the intent was to enforce the use of std::unique_lock, then why couldn't the following be used:

template<class Predicate, class Lock=std::mutex>
void wait(std::unique_lock<Lock> &lock, Predicate pred);

  1. how to reasonably get around this?

Edit

As explained by @Lingxi, and further pointed out by @T.C, the absolutely correct and very simple solution here is to use condition_variable_any, which was designed for stuff like this.

Aucun commentaire:

Enregistrer un commentaire