template <typename Func>
void setFn(Func&& fn) {
+ static_assert(
+ std::is_nothrow_constructible<
+ folly::Function<void()>,
+ _t<std::decay<Func>>>::value,
+ "Try using a smaller function object that can fit in folly::Function "
+ "without allocation, or use the custom interface of requestFC() to "
+ "manage the requested function's arguments and results explicitly "
+ "in a custom request structure without allocation.");
fn_ = std::forward<Func>(fn);
assert(fn_);
- // If the following assertion is triggered, the user should
- // either change the provided function, i.e., fn, to fit in
- // folly::Function without allocation or use the custom
- // interface to request combining for fn and manage its
- // arguments (and results, if any) explicitly in a custom
- // request structure.
- assert(!fn_.hasAllocatedMemory());
}
void clearFn() {
m_.lock();
}
+ // Give the caller exclusive access through a lock holder.
+ // No need for explicit release.
+ template <typename LockHolder>
+ void acquireExclusive(LockHolder& l) {
+ l = LockHolder(m_);
+ }
+
// Try to give the caller exclusive access. Returns true iff successful.
bool tryExclusive() {
return m_.try_lock();
}
if (excl) {
- // test of unstructured exclusive access
+ // test of exclusive access through a lock holder
+ {
+ std::unique_lock<Mutex> l;
+ ex.acquireExclusive(l);
+ CHECK(!mutex);
+ mutex = true;
+ VLOG(2) << tid << " " << ex.getVal() << " ...........";
+ using namespace std::chrono_literals;
+ /* sleep override */ // for coverage
+ std::this_thread::sleep_for(10ms);
+ VLOG(2) << tid << " " << ex.getVal() << " ===========";
+ CHECK(mutex);
+ mutex = false;
+ }
+ // test of explicit acquisition and release of exclusive access
ex.acquireExclusive();
{
CHECK(!mutex);