Boost logo

Boost :

From: Vinícius dos Santos Oliveira (vini.ipsmaker_at_[hidden])
Date: 2019-08-07 10:02:54


Just to share a report on experience with this approach,

Em qua, 15 de ago de 2018 às 09:06, Vinícius dos Santos Oliveira <
vini.ipsmaker_at_[hidden]> escreveu:

> [...] allows you to mark certain blocks as “atomic in respect to
> coroutines” using C++11 attributes.
>
> Usage example follows:
>
> void f() {
> int yield;
> g(yield);
> [[bt::forbid_suspend]] {
> // Comment this call to make linter accept the code
> g(yield);
> t();
> }
> }
>

Well, I've stumbled on limitations for this solution as I had to re-enable
suspensions on the middle of a block. Something like:

std::visit([&](auto& e) {
  using T = std::decay_t<decltype(e)>;
  if constexpr (std::is_same_v<T, A>) {
    auto msg = generate_msg(view, e);
    foo.async_write(msg, this_fiber);
    // from here we shouldn't touch
    // `view` again

So I've developed another approach, an assert_exclusive_strand_ref<T>.
Explanation and examples can be found on the documentation:
https://htmlpreview.github.io/?https://github.com/vinipsmaker/iofiber/blob/gh-pages/ref/assert_exclusive_strand_ref/index.html

This is not a new problem. It is know for some time. For instance, in
> P0171, Gor Nishanov noted this same problem:
>
> “In coroutines the suspend point is clearly marked with await, which tells
> the reader that something unusual happens in this function and allows the
> reader, for example, to confirm whether the lifetimes of the objects of
> interest align with the lifetime of the coroutine or not, whether some
> locks need to be acquired to protect some concurrently accessed data, and
> whether some locks need to be released before the execution reaches the
> suspend point.”
> — <http://open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0171r0.html>,
> 2015
>

I expanded my previous thoughts on this argument on the
assert_exclusive_strand_ref<T> documentation.

“Since we are on the subject of maintenance nightmares, we would like to
> offer a conjecture that the absence of the await in P0114 is a likely
> source of many maintenance nightmares. Without a syntactic marker to signal
> to the person reading the code that something funny is going on, it is
> impossible to tell whether the following code is correct or not”
> — http://open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0171r0.html
>

Can be done. Just like the compiler helps with static_assert, it can help
with some static_assert_{forbid,allow}_suspend() and these asserts can in
turn be used to build abstractions just like the
assert_exclusive_strand_ref<T>.

I've converted a few scary code sections from my job to use
assert_exclusive_strand_ref<T> instead relying on manually inspecting every
this_fiber usage throughout the code. From personal experience:

   - The this_fiber argument in the end of every suspending function worked
   as a hinted mark.
   - Manually looking for suspension points to analyze function behaviours
   acted precisely as a maintenance nightmare. I've lost hours on very small
   blocks of code.
   - Relying on alternative approaches — the forbid suspend block that I've
   abandoned and the new alternative — gave me much more confidence on the
   codes as (1) the code became less brittle and (2) it was easier to analyze
   the code.

[1] this_fiber completion token has a similar “mark” effect as the await
keyword

-- 
Vinícius dos Santos Oliveira
https://vinipsmaker.github.io/

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk