Using fibers to expand a thread’s stack at runtime, part 4

This post has been republished via RSS; it originally appeared at: Microsoft Developer Blogs.

Last time, we transported some ephemeral error state from the temporary fiber to the originating thread. A common way of reporting an error in C++ is to use an exception, so let's use that. In this case, we capture the result of the callback with a std::variant of an exception_ptr or the formal return value. The exception_ptr is used if the callback threw an exception. The exception_ptr is the first type in the variant because the RetType may not be default-constructible, and even if it has a default constructor, that default constructor may be heavy with unwanted side-effects. Putting the exception_ptr as the first type in the variant means that the default constructor for the variant creates an exception_ptr, which is default-constructible. We then ask Run­On­Fiber­Type­Neutral to do the fiber magic. If it failed, then we use some program-specific Throw­Win32­Error() function to transform the Win32 error into some kind of an exception. Otherwise, we know that the fiber ran to completion. In the fiber procedure, we call the callback and we save the result in the capturedValue variable as the RetType. If the callback threw an exception, we catch the exception and stow it in the capturedValue as an exception_ptr. After returning to the original thread, we keep inside the variant to see whether it holds an exception or a value. If it holds an exception, we rethrow it. Otherwise, we return the value. We must use the explicit index versions of variant::emplace, get, and get_if rather than the more readable type-based versions because the type-based version won't work if the RetType is exception_ptr! Observe that the RetType is always moved. There is no requirement that it be default-constructible or copyable. Note that the above code does not work if the lambda returns a reference. I'll leave that as an exercise. Even if you don't plan on working with fibers, this series showed how to transport state between threads, which is still useful. But wait, our discussion of using fibers to expand a stack dynamically isn't over. We'll pick up additional topics next time.

REMEMBER: these articles are REPUBLISHED. Your best bet to get a reply is to follow the link at the top of the post to the ORIGINAL post! BUT you're more than welcome to start discussions here:

This site uses Akismet to reduce spam. Learn how your comment data is processed.