diff --git a/folly/fibers/README.md b/folly/fibers/README.md index f5869f04607..7675f5c10bd 100644 --- a/folly/fibers/README.md +++ b/folly/fibers/README.md @@ -15,13 +15,13 @@ fiberManager.addTask([&]() { std::cout << "Task 1: start" << std::endl; baton.wait(); - std::cout << "Task 1: after baton.wait()" << std::endl; + std::cout << "Task 1: after baton.wait()" << std::endl; }); fiberManager.addTask([&]() { std::cout << "Task 2: start" << std::endl; baton.post(); - std::cout << "Task 2: after baton.post()" << std::endl; + std::cout << "Task 2: after baton.post()" << std::endl; }); evb.loop(); @@ -76,7 +76,7 @@ fiberManager.addTask([&]() { std::cout << "Task: start" << std::endl; baton.wait(); - std::cout << "Task: after baton.wait()" << std::endl; + std::cout << "Task: after baton.wait()" << std::endl; }); evb.loop(); @@ -116,7 +116,7 @@ ... Response response; fibers::Baton baton; - + asyncCall(request, [&](Response r) mutable { response = std::move(r); baton.post(); @@ -190,7 +190,7 @@
fiberManager.addTask([]() { ... auto response = asyncCallFuture(request).get(); - + // Now response holds response returned by the async call ... }
... Context context; - + asyncCall(request, [request, context](Response response) mutable { doSomething(request, response, context); }); @@ -242,7 +242,7 @@ Context context; auto response = fiberCall(request); - + doSomething(request, response, context); ... });
Similarly to system threads, every fiber-task has some stack space assigned to it. Stack usage goes up with the number of nested function calls and objects allocated on the stack. folly::fibers implementation only supports fiber-tasks with fixed stack size. If you want to have many fiber-tasks running concurrently - you need to reduce the amount of stack assigned to each fiber-task, otherwise you may run out of memory.
-However if you know that some function never suspends a fiber-task, you can use fibers::runInMainContext to safely call it from a fiber-task, without any risk of running out of stack space of the fiber-task.
@@ -308,7 +308,7 @@First fiber-task will grab a lock and then suspend waiting on a fibers::Baton. Then second fiber-task will be run and it will try to grab a lock. Unlike system threads, fiber-task can be only suspended explicitly, so the whole system thread will be blocked waiting on the lock, and we end up with a dead-lock.
-There're generally two ways we can solve this problem. Ideally we would re-design the program to never not hold any locks when fiber-task is suspended. However if we are absolutely sure we need that lock - folly::fibers library provides some fiber-task-aware lock implementations (e.g. +
There're generally two ways we can solve this problem. Ideally we would re-design the program to never not hold any locks when fiber-task is suspended. However if we are absolutely sure we need that lock - folly::fibers library provides some fiber-task-aware lock implementations (e.g. TimedMutex).
All of the features of folly::fibers library are actually built on top a single synchronization primitive called Baton. fibers::Baton is a fiber-specific version of folly::Baton. It only supports two basic operations: wait() and post(). Whenever wait() is called on the Baton, the current thread or fiber-task is suspended, until post() is called on the same Baton. wait() does not suspend the thread or fiber-task if post() was already called on the Baton. Please refer to Baton for more detailed documentation.
@@ -410,7 +410,7 @@ }); auto future2 = fiberManager.addTaskRemoteFuture([]() { ... - }); + }); auto result1 = future1.get(); auto result2 = future2.get();