On 9/7/2015 12:52 PM, Agustín K-ballo Bergé wrote:
On 9/4/2015 12:14 PM, Nat Goodspeed wrote:
Hi all,
The mini-review of Boost.Fiber by Oliver Kowalke begins today, Friday September 4th, and closes Sunday September 13th. It was reviewed in January 2014; the verdict at that time was "not in its present form." Since then Oliver has substantially improved documentation, performance, library customization and the underlying implementation, and is bringing the library back for mini-review.
The substance of the library API remains the same, which is why a mini-review is appropriate.
I had a look at `condition_variable[_any]` documentation, and was surprised to see that those two classes are guaranteed to be just aliases to a single implementation.
A bit more on the subject, the documentation for `wait()` states: "Precondition: lk is locked by the current fiber, and either no other fiber is currently waiting on *this, or the execution of the mutex() member function on the lk objects supplied in the calls to wait in all the fibers currently waiting on *this would return the same value as lk->mutex() for this call to wait." This seems to come directly from the standard, where it applies only to `condition_variable` and not `condition_variable_any`. Not only `condition_variable_any` does not have that precondition, it doesn't even require `lk->mutex()` to be well-formed. Your implementation doesn't seem to have those requirements, since (I assume) it works fine for `condition_variable_any`. "Note: The Precondition is a bit dense. It merely states that all the fibers calling wait on *this must wait on lk objects governing the same mutex." Fine, sans **currently**... "Three distinct objects are involved in any condition_variable::wait() call: the condition_variable itself, the mutex coordinating access between fibers and a lock object (e.g. std::unique_lock)." I wouldn't call a "call" an "object", but fine... "In some sense it would be nice if the condition_variable's constructor could accept the related mutex object, enforcing agreement across all wait() calls; but the existing APIs prevent that." One does not necessarily need to use the same mutex with a single condition variable over and over again, the requirement applies to concurrent waiters only (and again only for `condition_variable`). "Instead we must require the wait() call to accept a reference to the local lock object." Indeed you must, since the user will have to do some checks under the lock before calling `wait()`, and those and the wait must happen atomically (or else risks forever sleeping). "It is an error to reuse a given condition_variable instance with lock objects that reference different underlying mutex objects. It would be like a road intersection with traffic lights independent of one another: sooner or later a collision will result. " This states a different *stronger* requirement than the precondition, so which is it? Long story short, as far as I understand `condition_variable` allows for a more efficient implementation where the lock used to protect the variable is also used to protect the condition internal structures, while `condition_variable_any` needs an internal lock of its own. But I never quite fully understood their differences, and I wasn't present for the discussion, so perhaps someone else can enlighten us. Regards, -- Agustín K-ballo Bergé.- http://talesofcpp.fusionfenix.com