Commit Graph

6 Commits

Author SHA1 Message Date
Nadav Har'El
9b63b02328 doc: fix small mixup in reference (pipe.hh)
Signed-off-by: Nadav Har'El <nyh@cloudius-systems.com>
2015-07-07 12:57:09 +03:00
Avi Kivity
af30fe11df doc: more info in fiber module reference table 2015-07-07 00:38:53 +03:00
Avi Kivity
1501b273f6 doc: add reference section to fiber module 2015-07-07 00:29:23 +03:00
Nadav Har'El
a349f373b4 pipe: avoid needless use of exceptions
When closing the read-end side of the pipe, we need to notify the writer
only if it was blocked in write() on a full pipe - because if it wasn't
blocked, it will get the broken pipe on the next write() attempt.

We used queue::abort() for that, which is fine, because this function
won't do anything if nobody is waiting on a full buffer. But we still
call std::make_exception_ptr() unconditionally, which is slow (involves
throwing an exception and catching it) and an annoying false-alarm when
trying to debug with gdb's "catch throw" (which stops on any throw).

So this patch does

       if (_buf.full()) {
            _buf.abort(std::make_exception_ptr(broken_pipe_exception()));
       }

So that in the typical case when the buffer was not full (hopefully it
is empty), we don't do anything.

Signed-off-by: Nadav Har'El <nyh@cloudius-systems.com>
2015-06-25 17:03:52 +03:00
Nadav Har'El
13a68fa62c pipe: fix syntax error in pipe reader
I'm not sure how my compiler didn't complain earlier...

Signed-off-by: Nadav Har'El <nyh@cloudius-systems.com>
2015-06-20 11:07:06 +03:00
Nadav Har'El
2f4e123eab core: pipe for passing data between fibers
Our queue<T> is a convenient mechanism for passing data between a producer
fiber (a set of consecutive continuations) and a consumer fiber.

However, queue<T> is difficult to use *correctly*. The biggest problem is
how to handle premature stopping: What if one of the two fibers (the reader
or the writer) stops prematurely, and will never read or write any more?
When queue<T> is used naively, the other fiber will just hang indefinitely
while it waits to read from the empty queue, or write to the full queue.

The solution proposed in this patch is a new pipe mechanism, implemented
internally over a queue. pipe<T>() returns two separate objects - a pipe
reader, and a pipe writer. Typically each object is std::move()ed into a
different fiber. When a fiber stops and its captured variables are destroyed,
one end of the pipe is destroyed, and that causes the other end's operations
to return immediately (if the other end was already blocked, it will resume
immediately, and return an exceptions). This behavior is analogous to
Unix's EOF or broken-pipe behavior.

Signed-off-by: Nadav Har'El <nyh@cloudius-systems.com>
2015-06-19 19:03:13 +03:00