/*
- * Copyright 2016 Facebook, Inc.
+ * Copyright 2014-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
bool taskAdded = false;
size_t iterations = 0;
- FiberManager manager(folly::make_unique<SimpleLoopController>());
+ FiberManager manager(std::make_unique<SimpleLoopController>());
auto& loopController =
dynamic_cast<SimpleLoopController&>(manager.loopController());
manager.addTask([&]() {
Baton baton;
- auto res = baton.timed_wait(std::chrono::milliseconds(230));
+ auto res = baton.try_wait_for(std::chrono::milliseconds(230));
EXPECT_FALSE(res);
EXPECT_EQ(5, iterations);
manager.addTask([&]() {
Baton baton;
- auto res = baton.timed_wait(std::chrono::milliseconds(130));
+ auto res = baton.try_wait_for(std::chrono::milliseconds(130));
EXPECT_FALSE(res);
EXPECT_EQ(3, iterations);
size_t iterations = 0;
Baton* baton_ptr;
- FiberManager manager(folly::make_unique<SimpleLoopController>());
+ FiberManager manager(std::make_unique<SimpleLoopController>());
auto& loopController =
dynamic_cast<SimpleLoopController&>(manager.loopController());
Baton baton;
baton_ptr = &baton;
- auto res = baton.timed_wait(std::chrono::milliseconds(130));
+ auto res = baton.try_wait_for(std::chrono::milliseconds(130));
EXPECT_TRUE(res);
EXPECT_EQ(2, iterations);
folly::EventBase evb;
- FiberManager manager(folly::make_unique<EventBaseLoopController>());
+ FiberManager manager(std::make_unique<EventBaseLoopController>());
dynamic_cast<EventBaseLoopController&>(manager.loopController())
.attachEventBase(evb);
Baton baton;
auto start = EventBaseLoopController::Clock::now();
- auto res = baton.timed_wait(std::chrono::milliseconds(timeout_ms));
+ auto res = baton.try_wait_for(std::chrono::milliseconds(timeout_ms));
auto finish = EventBaseLoopController::Clock::now();
EXPECT_FALSE(res);
folly::EventBase evb;
- FiberManager manager(folly::make_unique<EventBaseLoopController>());
+ FiberManager manager(std::make_unique<EventBaseLoopController>());
dynamic_cast<EventBaseLoopController&>(manager.loopController())
.attachEventBase(evb);
evb.tryRunAfterDelay([&]() { baton.post(); }, 100);
auto start = EventBaseLoopController::Clock::now();
- auto res = baton.timed_wait(std::chrono::milliseconds(130));
+ auto res = baton.try_wait_for(std::chrono::milliseconds(130));
auto finish = EventBaseLoopController::Clock::now();
EXPECT_TRUE(res);
}
TEST(FiberManager, batonTryWait) {
- FiberManager manager(folly::make_unique<SimpleLoopController>());
+ FiberManager manager(std::make_unique<SimpleLoopController>());
// Check if try_wait and post work as expected
Baton b;
}
TEST(FiberManager, genericBatonFiberWait) {
- FiberManager manager(folly::make_unique<SimpleLoopController>());
+ FiberManager manager(std::make_unique<SimpleLoopController>());
GenericBaton b;
bool fiberRunning = false;
}
TEST(FiberManager, genericBatonThreadWait) {
- FiberManager manager(folly::make_unique<SimpleLoopController>());
+ FiberManager manager(std::make_unique<SimpleLoopController>());
GenericBaton b;
std::atomic<bool> threadWaiting(false);
std::vector<Promise<int>> pendingFibers;
bool taskAdded = false;
- FiberManager manager(folly::make_unique<SimpleLoopController>());
+ FiberManager manager(std::make_unique<SimpleLoopController>());
auto& loopController =
dynamic_cast<SimpleLoopController&>(manager.loopController());
if (!taskAdded) {
manager.addTask([&]() {
std::vector<std::function<std::unique_ptr<int>()>> funcs;
- for (size_t i = 0; i < 3; ++i) {
+ for (int i = 0; i < 3; ++i) {
funcs.push_back([i, &pendingFibers]() {
await([&pendingFibers](Promise<int> promise) {
pendingFibers.push_back(std::move(promise));
});
- return folly::make_unique<int>(i * 2 + 1);
+ return std::make_unique<int>(i * 2 + 1);
});
}
getFiberManager(evb)
.addTaskFuture([&] {
EXPECT_THROW(
- await([](Promise<int> p) {
+ await([](Promise<int> p) {
p.setValue(42);
throw ExpectedException();
}),
- ExpectedException
- );
+ ExpectedException);
EXPECT_THROW(
- await([&](Promise<int> p) {
+ await([&](Promise<int> p) {
evb.runInEventBaseThread([p = std::move(p)]() mutable {
- p.setValue(42);
- });
+ p.setValue(42);
+ });
throw ExpectedException();
}),
- ExpectedException);
+ ExpectedException);
})
.waitVia(&evb);
}
std::vector<Promise<int>> pendingFibers;
bool taskAdded = false;
- FiberManager manager(folly::make_unique<SimpleLoopController>());
+ FiberManager manager(std::make_unique<SimpleLoopController>());
auto& loopController =
dynamic_cast<SimpleLoopController&>(manager.loopController());
std::vector<Promise<int>> pendingFibers;
bool taskAdded = false;
- FiberManager manager(folly::make_unique<SimpleLoopController>());
+ FiberManager manager(std::make_unique<SimpleLoopController>());
auto& loopController =
dynamic_cast<SimpleLoopController&>(manager.loopController());
manager.addTask([&]() {
std::vector<std::function<void()>> funcs;
for (size_t i = 0; i < 3; ++i) {
- funcs.push_back([i, &pendingFibers]() {
+ funcs.push_back([&pendingFibers]() {
await([&pendingFibers](Promise<int> promise) {
pendingFibers.push_back(std::move(promise));
});
std::vector<Promise<int>> pendingFibers;
bool taskAdded = false;
- FiberManager manager(folly::make_unique<SimpleLoopController>());
+ FiberManager manager(std::make_unique<SimpleLoopController>());
auto& loopController =
dynamic_cast<SimpleLoopController&>(manager.loopController());
std::vector<Promise<int>> pendingFibers;
bool taskAdded = false;
- FiberManager manager(folly::make_unique<SimpleLoopController>());
+ FiberManager manager(std::make_unique<SimpleLoopController>());
auto& loopController =
dynamic_cast<SimpleLoopController&>(manager.loopController());
std::vector<Promise<int>> pendingFibers;
bool taskAdded = false;
- FiberManager manager(folly::make_unique<SimpleLoopController>());
+ FiberManager manager(std::make_unique<SimpleLoopController>());
auto& loopController =
dynamic_cast<SimpleLoopController&>(manager.loopController());
std::vector<Promise<int>> pendingFibers;
bool taskAdded = false;
- FiberManager manager(folly::make_unique<SimpleLoopController>());
+ FiberManager manager(std::make_unique<SimpleLoopController>());
auto& loopController =
dynamic_cast<SimpleLoopController&>(manager.loopController());
std::vector<Promise<int>> pendingFibers;
bool taskAdded = false;
- FiberManager manager(folly::make_unique<SimpleLoopController>());
+ FiberManager manager(std::make_unique<SimpleLoopController>());
auto& loopController =
dynamic_cast<SimpleLoopController&>(manager.loopController());
manager.addTask([&]() {
std::vector<std::function<int()>> funcs;
for (size_t i = 0; i < 3; ++i) {
- funcs.push_back([i, &pendingFibers]() -> size_t {
+ funcs.push_back([&pendingFibers]() -> size_t {
await([&pendingFibers](Promise<int> promise) {
pendingFibers.push_back(std::move(promise));
});
std::vector<Promise<int>> pendingFibers;
bool taskAdded = false;
- FiberManager manager(folly::make_unique<SimpleLoopController>());
+ FiberManager manager(std::make_unique<SimpleLoopController>());
auto& loopController =
dynamic_cast<SimpleLoopController&>(manager.loopController());
manager.addTask([&]() {
std::vector<std::function<void()>> funcs;
for (size_t i = 0; i < 3; ++i) {
- funcs.push_back([i, &pendingFibers]() {
+ funcs.push_back([&pendingFibers]() {
await([&pendingFibers](Promise<int> promise) {
pendingFibers.push_back(std::move(promise));
});
std::vector<Promise<int>> pendingFibers;
bool taskAdded = false;
- FiberManager manager(folly::make_unique<SimpleLoopController>());
+ FiberManager manager(std::make_unique<SimpleLoopController>());
auto& loopController =
dynamic_cast<SimpleLoopController&>(manager.loopController());
manager.addTask([&]() {
std::vector<std::function<void()>> funcs;
for (size_t i = 0; i < 3; ++i) {
- funcs.push_back([i, &pendingFibers]() {
+ funcs.push_back([&pendingFibers]() {
await([&pendingFibers](Promise<int> promise) {
pendingFibers.push_back(std::move(promise));
});
std::vector<Promise<int>> pendingFibers;
bool taskAdded = false;
- FiberManager manager(folly::make_unique<SimpleLoopController>());
+ FiberManager manager(std::make_unique<SimpleLoopController>());
auto& loopController =
dynamic_cast<SimpleLoopController&>(manager.loopController());
std::vector<Promise<int>> pendingFibers;
bool taskAdded = false;
- FiberManager manager(folly::make_unique<SimpleLoopController>());
+ FiberManager manager(std::make_unique<SimpleLoopController>());
auto& loopController =
dynamic_cast<SimpleLoopController&>(manager.loopController());
manager.addTask([&]() {
std::vector<std::function<void()>> funcs;
for (size_t i = 0; i < 3; ++i) {
- funcs.push_back([i, &pendingFibers]() {
+ funcs.push_back([&pendingFibers]() {
await([&pendingFibers](Promise<int> promise) {
pendingFibers.push_back(std::move(promise));
});
std::vector<Promise<int>> pendingFibers;
bool taskAdded = false;
- FiberManager manager(folly::make_unique<SimpleLoopController>());
+ FiberManager manager(std::make_unique<SimpleLoopController>());
auto& loopController =
dynamic_cast<SimpleLoopController&>(manager.loopController());
void expectMainContext(bool& ran, int* mainLocation, int* fiberLocation) {
int here;
/* 2 pages is a good guess */
- constexpr ssize_t DISTANCE = 0x2000 / sizeof(int);
+ constexpr auto const kHereToFiberMaxDist = 0x2000 / sizeof(int);
+
+ // With ASAN's detect_stack_use_after_return=1, this must be much larger
+ // I measured 410028 on x86_64, so allow for quadruple that, just in case.
+ constexpr auto const kHereToMainMaxDist =
+ folly::kIsSanitizeAddress ? 4 * 410028 : kHereToFiberMaxDist;
+
if (fiberLocation) {
- EXPECT_TRUE(std::abs(&here - fiberLocation) > DISTANCE);
+ EXPECT_GT(std::abs(&here - fiberLocation), kHereToFiberMaxDist);
}
if (mainLocation) {
- EXPECT_TRUE(std::abs(&here - mainLocation) < DISTANCE);
+ EXPECT_LT(std::abs(&here - mainLocation), kHereToMainMaxDist);
}
EXPECT_FALSE(ran);
ran = true;
}
-}
+} // namespace
TEST(FiberManager, runInMainContext) {
- FiberManager manager(folly::make_unique<SimpleLoopController>());
+ FiberManager manager(std::make_unique<SimpleLoopController>());
auto& loopController =
dynamic_cast<SimpleLoopController&>(manager.loopController());
}
TEST(FiberManager, addTaskFinally) {
- FiberManager manager(folly::make_unique<SimpleLoopController>());
+ FiberManager manager(std::make_unique<SimpleLoopController>());
auto& loopController =
dynamic_cast<SimpleLoopController&>(manager.loopController());
FiberManager::Options opts;
opts.maxFibersPoolSize = 5;
- FiberManager manager(folly::make_unique<SimpleLoopController>(), opts);
+ FiberManager manager(std::make_unique<SimpleLoopController>(), opts);
auto& loopController =
dynamic_cast<SimpleLoopController&>(manager.loopController());
FiberManager::Options opts;
opts.maxFibersPoolSize = 5;
- FiberManager manager(folly::make_unique<SimpleLoopController>(), opts);
+ FiberManager manager(std::make_unique<SimpleLoopController>(), opts);
auto& loopController =
dynamic_cast<SimpleLoopController&>(manager.loopController());
}
TEST(FiberManager, remoteFiberBasic) {
- FiberManager manager(folly::make_unique<SimpleLoopController>());
+ FiberManager manager(std::make_unique<SimpleLoopController>());
auto& loopController =
dynamic_cast<SimpleLoopController&>(manager.loopController());
}
TEST(FiberManager, addTaskRemoteBasic) {
- FiberManager manager(folly::make_unique<SimpleLoopController>());
+ FiberManager manager(std::make_unique<SimpleLoopController>());
int result[2];
result[0] = result[1] = 0;
TEST(FiberManager, remoteHasTasks) {
size_t counter = 0;
- FiberManager fm(folly::make_unique<SimpleLoopController>());
+ FiberManager fm(std::make_unique<SimpleLoopController>());
std::thread remote([&]() { fm.addTaskRemote([&]() { ++counter; }); });
remote.join();
TEST(FiberManager, remoteHasReadyTasks) {
int result = 0;
folly::Optional<Promise<int>> savedPromise;
- FiberManager fm(folly::make_unique<SimpleLoopController>());
+ FiberManager fm(std::make_unique<SimpleLoopController>());
std::thread remote([&]() {
fm.addTaskRemote([&]() {
result = await(
template <typename Data>
void testFiberLocal() {
- FiberManager fm(
- LocalType<Data>(), folly::make_unique<SimpleLoopController>());
+ FiberManager fm(LocalType<Data>(), std::make_unique<SimpleLoopController>());
fm.addTask([]() {
EXPECT_EQ(42, local<Data>().value);
};
FiberManager fm(
- LocalType<CrazyData>(), folly::make_unique<SimpleLoopController>());
+ LocalType<CrazyData>(), std::make_unique<SimpleLoopController>());
fm.addTask([]() { local<CrazyData>().data = 41; });
}
TEST(FiberManager, yieldTest) {
- FiberManager manager(folly::make_unique<SimpleLoopController>());
+ FiberManager manager(std::make_unique<SimpleLoopController>());
auto& loopController =
dynamic_cast<SimpleLoopController&>(manager.loopController());
}
TEST(FiberManager, RequestContext) {
- FiberManager fm(folly::make_unique<SimpleLoopController>());
+ FiberManager fm(std::make_unique<SimpleLoopController>());
bool checkRun1 = false;
bool checkRun2 = false;
opts.fibersPoolResizePeriodMs = 300;
opts.maxFibersPoolSize = 5;
- FiberManager manager(folly::make_unique<EventBaseLoopController>(), opts);
+ FiberManager manager(std::make_unique<EventBaseLoopController>(), opts);
folly::EventBase evb;
dynamic_cast<EventBaseLoopController&>(manager.loopController())
}
TEST(FiberManager, batonWaitTimeoutHandler) {
- FiberManager manager(folly::make_unique<EventBaseLoopController>());
+ FiberManager manager(std::make_unique<EventBaseLoopController>());
folly::EventBase evb;
dynamic_cast<EventBaseLoopController&>(manager.loopController())
}
TEST(FiberManager, batonWaitTimeoutMany) {
- FiberManager manager(folly::make_unique<EventBaseLoopController>());
+ FiberManager manager(std::make_unique<EventBaseLoopController>());
folly::EventBase evb;
dynamic_cast<EventBaseLoopController&>(manager.loopController())
}
TEST(FiberManager, remoteFutureTest) {
- FiberManager fiberManager(folly::make_unique<SimpleLoopController>());
+ FiberManager fiberManager(std::make_unique<SimpleLoopController>());
auto& loopController =
dynamic_cast<SimpleLoopController&>(fiberManager.loopController());
// Test that a void function produes a Future<Unit>.
TEST(FiberManager, remoteFutureVoidUnitTest) {
- FiberManager fiberManager(folly::make_unique<SimpleLoopController>());
+ FiberManager fiberManager(std::make_unique<SimpleLoopController>());
auto& loopController =
dynamic_cast<SimpleLoopController&>(fiberManager.loopController());
}
TEST(FiberManager, semaphore) {
- constexpr size_t kTasks = 10;
- constexpr size_t kIterations = 10000;
- constexpr size_t kNumTokens = 10;
+ static constexpr size_t kTasks = 10;
+ static constexpr size_t kIterations = 10000;
+ static constexpr size_t kNumTokens = 10;
Semaphore sem(kNumTokens);
int counterA = 0;
int counterB = 0;
- auto task = [&sem, kTasks, kIterations, kNumTokens](
- int& counter, folly::fibers::Baton& baton) {
- FiberManager manager(folly::make_unique<EventBaseLoopController>());
+ auto task = [&sem](int& counter, folly::fibers::Baton& baton) {
+ FiberManager manager(std::make_unique<EventBaseLoopController>());
folly::EventBase evb;
dynamic_cast<EventBaseLoopController&>(manager.loopController())
.attachEventBase(evb);
std::vector<int>,
std::vector<std::string>,
ExecutorT>
- batchDispatcher(executor, [=](std::vector<std::vector<int>>&& batch) {
- std::vector<std::vector<std::string>> results;
- int numberOfElements = 0;
- for (auto& unit : batch) {
- numberOfElements += unit.size();
- std::vector<std::string> result;
- for (auto& element : unit) {
- result.push_back(folly::to<std::string>(element));
- }
- results.push_back(std::move(result));
- }
- EXPECT_EQ(totalNumberOfElements, numberOfElements);
- return results;
- });
+ batchDispatcher(executor, [=](std::vector<std::vector<int>>&& batch) {
+ std::vector<std::vector<std::string>> results;
+ int numberOfElements = 0;
+ for (auto& unit : batch) {
+ numberOfElements += unit.size();
+ std::vector<std::string> result;
+ for (auto& element : unit) {
+ result.push_back(folly::to<std::string>(element));
+ }
+ results.push_back(std::move(result));
+ }
+ EXPECT_EQ(totalNumberOfElements, numberOfElements);
+ return results;
+ });
return batchDispatcher.add(std::move(input));
}
ExecutorT& executor,
int totalNumberOfElements,
int index) {
- thread_local BatchDispatcher<int, std::string, ExecutorT>
- batchDispatcher(executor, [=, &executor](std::vector<int>&& batch) {
- EXPECT_EQ(totalNumberOfElements, batch.size());
- std::vector<std::string> results;
- std::vector<folly::Future<std::vector<std::string>>>
- innerDispatchResultFutures;
-
- std::vector<int> group;
- for (auto unit : batch) {
- group.push_back(unit);
- if (group.size() == 5) {
- auto localGroup = group;
- group.clear();
-
- innerDispatchResultFutures.push_back(doubleBatchInnerDispatch(
- executor, totalNumberOfElements, localGroup));
- }
- }
-
- folly::collectAll(
- innerDispatchResultFutures.begin(), innerDispatchResultFutures.end())
- .then([&](
- std::vector<Try<std::vector<std::string>>> innerDispatchResults) {
- for (auto& unit : innerDispatchResults) {
- for (auto& element : unit.value()) {
- results.push_back(element);
- }
+ thread_local BatchDispatcher<int, std::string, ExecutorT> batchDispatcher(
+ executor, [=, &executor](std::vector<int>&& batch) {
+ EXPECT_EQ(totalNumberOfElements, batch.size());
+ std::vector<std::string> results;
+ std::vector<folly::Future<std::vector<std::string>>>
+ innerDispatchResultFutures;
+
+ std::vector<int> group;
+ for (auto unit : batch) {
+ group.push_back(unit);
+ if (group.size() == 5) {
+ auto localGroup = group;
+ group.clear();
+
+ innerDispatchResultFutures.push_back(doubleBatchInnerDispatch(
+ executor, totalNumberOfElements, localGroup));
}
- })
- .get();
- return results;
- });
+ }
+
+ folly::collectAll(
+ innerDispatchResultFutures.begin(),
+ innerDispatchResultFutures.end())
+ .then([&](std::vector<Try<std::vector<std::string>>>
+ innerDispatchResults) {
+ for (auto& unit : innerDispatchResults) {
+ for (auto& element : unit.value()) {
+ results.push_back(element);
+ }
+ }
+ })
+ .get();
+ return results;
+ });
auto indexCopy = index;
auto result = batchDispatcher.add(std::move(indexCopy));
template <typename ExecutorT>
void batchDispatchExceptionHandling(ExecutorT& executor, int i) {
thread_local BatchDispatcher<int, int, ExecutorT> batchDispatcher(
- executor, [=, &executor](std::vector<int> &&) -> std::vector<int> {
+ executor, [](std::vector<int> &&) -> std::vector<int> {
throw std::runtime_error("Surprise!!");
});
if (dispatchProblem == DispatchProblem::DuplicateDispatch) {
if (i == problemIndex) {
- EXPECT_THROW(job.token.dispatch(job.input), std::logic_error);
+ EXPECT_THROW(job.token.dispatch(job.input), ABDUsageException);
}
}
} catch (...) {
EXPECT_EQ(numResultsFilled, expectedNumResults);
}
-} // AtomicBatchDispatcherTesting
+} // namespace AtomicBatchDispatcherTesting
#define SET_UP_TEST_FUNC \
using namespace AtomicBatchDispatcherTesting; \
dispatchJobs(executor, jobs, results);
throw std::runtime_error(
"Unexpected exception in user code before commit called");
- atomicBatchDispatcher.commit();
+ // atomicBatchDispatcher.commit();
} catch (...) {
/* User code handles the exception and does not exit process */
}
evb.loop();
- validateResults<std::logic_error>(results, COUNT);
+ validateResults<ABDCommitNotCalledException>(results, COUNT);
}
TEST(FiberManager, ABD_PreprocessingFailureTest) {
dispatchJobs(executor, jobs, results, DispatchProblem::PreprocessThrows, 8);
atomicBatchDispatcher.commit();
evb.loop();
- validateResults<std::logic_error>(results, COUNT - 1);
+ validateResults<ABDTokenNotDispatchedException>(results, COUNT - 1);
}
TEST(FiberManager, ABD_MultipleDispatchOnSameTokenErrorTest) {
createAtomicBatchDispatcher(std::move(dispatchFunc));
createJobs(atomicBatchDispatcher, jobs, COUNT);
atomicBatchDispatcher.commit();
- EXPECT_THROW(atomicBatchDispatcher.getToken(), std::logic_error);
+ EXPECT_THROW(atomicBatchDispatcher.getToken(), ABDUsageException);
dispatchJobs(executor, jobs, results);
- EXPECT_THROW(atomicBatchDispatcher.getToken(), std::logic_error);
+ EXPECT_THROW(atomicBatchDispatcher.getToken(), ABDUsageException);
evb.loop();
validateResults(results, COUNT);
- EXPECT_THROW(atomicBatchDispatcher.getToken(), std::logic_error);
+ EXPECT_THROW(atomicBatchDispatcher.getToken(), ABDUsageException);
}
TEST(FiberManager, ABD_UserProvidedBatchDispatchThrowsTest) {
}
TEST(FiberManager, VirtualEventBase) {
- folly::ScopedEventBaseThread thread;
-
- auto evb1 =
- folly::make_unique<folly::VirtualEventBase>(*thread.getEventBase());
- auto evb2 =
- folly::make_unique<folly::VirtualEventBase>(*thread.getEventBase());
-
bool done1{false};
bool done2{false};
+ {
+ folly::ScopedEventBaseThread thread;
- getFiberManager(*evb1).addTaskRemote([&] {
- Baton baton;
- baton.timed_wait(std::chrono::milliseconds{100});
+ auto evb1 =
+ std::make_unique<folly::VirtualEventBase>(*thread.getEventBase());
+ auto& evb2 = thread.getEventBase()->getVirtualEventBase();
- done1 = true;
- });
+ getFiberManager(*evb1).addTaskRemote([&] {
+ Baton baton;
+ baton.try_wait_for(std::chrono::milliseconds{100});
- getFiberManager(*evb2).addTaskRemote([&] {
- Baton baton;
- baton.timed_wait(std::chrono::milliseconds{200});
+ done1 = true;
+ });
- done2 = true;
- });
+ getFiberManager(evb2).addTaskRemote([&] {
+ Baton baton;
+ baton.try_wait_for(std::chrono::milliseconds{200});
+
+ done2 = true;
+ });
- evb1.reset();
- EXPECT_TRUE(done1);
+ EXPECT_FALSE(done1);
+ EXPECT_FALSE(done2);
- evb2.reset();
+ evb1.reset();
+ EXPECT_TRUE(done1);
+ EXPECT_FALSE(done2);
+ }
EXPECT_TRUE(done2);
}
+TEST(TimedMutex, ThreadsAndFibersDontDeadlock) {
+ folly::EventBase evb;
+ auto& fm = getFiberManager(evb);
+ TimedMutex mutex;
+ std::thread testThread([&] {
+ for (int i = 0; i < 100; i++) {
+ mutex.lock();
+ mutex.unlock();
+ {
+ Baton b;
+ b.try_wait_for(std::chrono::milliseconds(1));
+ }
+ }
+ });
+
+ for (int numFibers = 0; numFibers < 100; numFibers++) {
+ fm.addTask([&] {
+ for (int i = 0; i < 20; i++) {
+ mutex.lock();
+ {
+ Baton b;
+ b.try_wait_for(std::chrono::milliseconds(1));
+ }
+ mutex.unlock();
+ {
+ Baton b;
+ b.try_wait_for(std::chrono::milliseconds(1));
+ }
+ }
+ });
+ }
+
+ evb.loop();
+ EXPECT_EQ(0, fm.hasTasks());
+ testThread.join();
+}
+
TEST(TimedMutex, ThreadFiberDeadlockOrder) {
folly::EventBase evb;
auto& fm = getFiberManager(evb);
*/
#ifndef FOLLY_SANITIZE_ADDRESS
TEST(FiberManager, recordStack) {
- std::thread([] {
+ auto f = [] {
folly::fibers::FiberManager::Options opts;
opts.recordStackEvery = 1;
- FiberManager fm(folly::make_unique<SimpleLoopController>(), opts);
+ FiberManager fm(std::make_unique<SimpleLoopController>(), opts);
auto& loopController =
dynamic_cast<SimpleLoopController&>(fm.loopController());
// Check that we properly accounted fiber stack usage.
EXPECT_LT(n * sizeof(int), fm.stackHighWatermark());
- }).join();
+ };
+ std::thread(f).join();
}
#endif