[svn] commit: r3126 - /branches/trac327/src/lib/asiolink/internal/coroutine.h
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed Oct 6 20:51:31 UTC 2010
Author: each
Date: Wed Oct 6 20:51:30 2010
New Revision: 3126
Log:
Added some documentation for coroutine.h
Modified:
branches/trac327/src/lib/asiolink/internal/coroutine.h
Modified: branches/trac327/src/lib/asiolink/internal/coroutine.h
==============================================================================
--- branches/trac327/src/lib/asiolink/internal/coroutine.h (original)
+++ branches/trac327/src/lib/asiolink/internal/coroutine.h Wed Oct 6 20:51:30 2010
@@ -11,6 +11,58 @@
#ifndef COROUTINE_HPP
#define COROUTINE_HPP
+
+// \brief Coroutine object
+//
+// A coroutine object maintains the state of a re-enterable routine. It
+// is assignable and copy-constructable, and can be used as a base class
+// for a class that uses it, or as a data member. The copy overhead is
+// a single int.
+//
+// A reenterable function contains a CORO_REENTER (coroutine) { ... }
+// block. Whenever an asychrnonous operation is initiated within the
+// routine, the function is provided as the handler object. (The simplest
+// way to do this is to have the reenterable function be the operator()
+// member for the coroutine object itself.) For example:
+//
+// CORO_YIELD socket->async_read_some(buffer, *this);
+//
+// The CORO_YIELD keyword updates the current status of the coroutine to
+// indicate the line number currently being executed. The
+// async_read_some() call is initiated, with a copy of the updated
+// corotutine as its handler object, and the current coroutine exits. When
+// the async_read_some() call finishes, the copied coroutine will be
+// called, and will resume processing exactly where the original one left
+// off--right after asynchronous call. This allows asynchronous I/O
+// routines to be written with a logical flow, step following step, rather
+// than as a linked chain of separate handler functions.
+//
+// When necessary, a coroutine can fork itself using the CORO_FORK keyword.
+// This updates the status of the coroutine and makes a copy. The copy can
+// then be called directly or posted to the ASIO service queue so that both
+// coroutines will continue forward, one "parent" and one "child". The
+// is_parent() and is_child() methods indicate which is which.
+//
+// The CORO_REENTER, CORO_YIELD and CORO_FORK keywords are implemented
+// via preprocessor macros. The CORO_REENTER block is actually a large,
+// complex switch statement. Because of this, inline variable declaration
+// is impossible within CORO_REENTER unless it is done in a subsidiary
+// scope--and if it is, that scope cannot contain CORO_YIELD or CORO_FORK
+// keywords.
+//
+// Because coroutines are frequently copied, it is best to minimize copy
+// overhead by limiting the size of data members in derived classes.
+//
+// It should be noted that when a coroutine falls out of scope its memory
+// is reclaimed, even though it may be scheduled to resume when an
+// asynchronous operation completes. Any shared_ptr<> objects declared in
+// the coroutine may be destroyed if their reference count drops to zero,
+// in which case the coroutine will have serious problems once it resumes.
+// One solution so this is to have the space that will be used by a
+// coroutine pre-allocated and stored on a free list; a new coroutine can
+// fetch the block of space off a free list, place a shared pointer to it
+// on an "in use" list, and carry on. The reference in the "in use" list
+// would prevent the data from being destroyed.
class coroutine
{
public:
More information about the bind10-changes
mailing list