# Chrome Network Stack Common Coding Patterns

## Combined error and byte count into a single value

At many places in the network stack, functions return a value that, if
positive, indicate a count of bytes that the the function read or
wrote, and if negative, indicates a network stack error code (see
[net_error_list.h][]).
Zero indicates either `net::OK` or zero bytes read (usually EOF)
depending on the context. This pattern is generally specified by
an `int` return type.

Many functions also have variables (often named `result` or `rv`) containing
such a value; this is especially common in the [DoLoop](#DoLoop) pattern
described below.

## Sync/Async Return

Many network stack routines may return synchronously or
asynchronously. These functions generally return an int as described
above. There are three cases:

* If the value is positive or zero, that indicates a synchronous
  successful return, with a zero return value indicating either zero
  bytes/EOF or indicating `net::OK`, depending on context.
* If the value is negative and != `net::ERR_IO_PENDING`, it is an error
  code specifying a synchronous failure.
* If the return value is the special value `net::ERR_IO_PENDING`, it
  indicates that the routine will complete asynchronously. A reference to
  any provided IOBuffer will be retained by the called entity until
  completion, to be written into or read from as required. 
  If there is a callback argument, that callback will be called upon
  completion with the return value; if there is no callback argument, it
  usually means that some known callback mechanism will be employed.

## DoLoop

The DoLoop pattern is used in the network stack to construct simple
state machines. It is used for cases in which processing is basically
single-threaded and could be written in a single function, if that
function could block waiting for input. Generally, initiation of a
state machine is triggered by some method invocation by a class
consumer, and that state machine is driven (possibly across
asynchronous IO initiated by the class) until the operation requested
by the method invocation completes, at which point the state variable is
set to `STATE_NONE` and the consumer notified.  

Cases which do not fit into this single-threaded, single consumer
operation model are generally adapted in some way to fit the model,
either by multiple state machines (e.g. independent state machines for
reading and writing, if each can be initiated while the other is
outstanding) or by storing information across consumer invocations and
returns that can be used to restart the state machine in the proper
state. 

Any class using this pattern will contain an enum listing all states
of that machine, and define a function, `DoLoop()`, to drive that state
machine. If a class has multiple state machines (as above) it will
have multiple methods (e.g. `DoReadLoop()` and `DoWriteLoop()`) to drive
those different machines.

The characteristics of the DoLoop pattern are:

*   Each state has a corresponding function which is called by `DoLoop()`
    for handling when the state machine is in that state. Generally the
    states are named STATE`_<`STATE_NAME`>` (upper case separated by
    underscores), and the routine is named Do`<`StateName`>` (CamelCase).
    For example:

         enum State {
             STATE_NONE, 
             STATE_INIT,
             STATE_FOO,
             STATE_FOO_COMPLETE,
         };
         int DoInit();
         int DoFoo();
         int DoFooComplete(int result);

*   Each state handling function has two basic responsibilities in
    addition to state specific handling: Setting the data member
    (named `next_state_` or something similar)
    to specify the next state, and returning a `net::Error` (or combined
    error and byte count, as above). 
    
*   On each `DoLoop()` iteration, the function saves the next state to a local
    variable and resets to a default state (`STATE_NONE`),
    and then calls the appropriate state handling based on the
    original value of the next state. This looks like:

           do {
             State state = io_state_;
             next_state_ = STATE_NONE;
             switch (state) {
               case STATE_INIT:
                 result = DoInit();
                 break;
               ...

    This pattern is followed primarily to ensure that in the event of
    a bug where the next state isn't set, the loop terminates rather
    than loops infinitely. It's not a perfect mitigation, but works
    well as a defensive measure.
    
*   If a given state may complete asynchronously (for example,
    writing to an underlying transport socket), then there will often
    be split states, such as `STATE_WRITE` and
    `STATE_WRITE_COMPLETE`. The first state is responsible for
    starting/continuing the original operation, while the second state
    is responsible for handling completion (e.g. success vs error,
    complete vs. incomplete writes), and determining the next state to
    transition to. 
    
*   While the return value from each call is propagated through the loop
    to the next state, it is expected that for most state transitions the
    return value will be `net::OK`, and that an error return will also
    set the state to `STATE_NONE` or fail to override the default
    assignment to `STATE_DONE` to exit the loop and return that 
    error to the caller. This is often asserted with a DCHECK, e.g.

            case STATE_FOO:
                DCHECK_EQ(result, OK);
                result = DoFoo();
                break;

    The exception to this pattern is split states, where an IO
    operation has been dispatched, and the second state is handling
    the result. In that case, the second state's function takes the
    result code:
    
            case STATE_FOO_COMPLETE:
                result = DoFooComplete(result);
                break;
    
*   If the return value from the state handling function is
    `net::ERR_IO_PENDING`, that indicates that the function has arranged
    for `DoLoop()` to be called at some point in the future, when further
    progress can be made on the state transitions. The `next_state_` variable
    will have been set to the proper value for handling that incoming
    call. In this case, `DoLoop()` will exit. This often occurs between
    split states, as described above. 
    
*   The DoLoop mechanism is generally invoked in response to a consumer
    calling one of its methods. While the operation that method
    requested is occuring, the state machine stays active, possibly
    over multiple asynchronous operations and state transitions. When
    that operation is complete, the state machine transitions to
    `STATE_NONE` (by a `DoLoop()` callee not setting `next_state_`) or
    explicitly to `STATE_DONE` (indicating that the operation is
    complete *and* the state machine is not amenable to further
    driving). At this point the consumer is notified of the completion
    of the operation (by synchronous return or asynchronous callback).
 
    Note that this implies that when `DoLoop()` returns, one of two
    things will be true:
 
    * The return value will be `net::ERR_IO_PENDING`, indicating that the
      caller should take no action and instead wait for asynchronous
      notification. 
    * The state of the machine will be either `STATE_DONE` or `STATE_NONE`,
      indicating that the operation that first initiated the `DoLoop()` has
      completed. 
 
    This invariant reflects and enforces the single-threaded (though
    possibly asynchronous) nature of the driven state machine--the
    machine is always executing one requested operation.
    
*   `DoLoop()` is called from two places: a) methods exposed to the consumer
    for specific operations (e.g. `ReadHeaders()`), and b) an IO completion
    callbacks called asynchronously by spawned IO operations.

    In the first case, the return value from `DoLoop()` is returned directly
    to the caller; if the operation completed synchronously, that will
    contain the operation result, and if it completed asynchronously, it
    will be `net::ERR_IO_PENDING`. For example (from 
    `HttpStreamParser`, abridged for clarity): 

             int HttpStreamParser::ReadResponseHeaders(
                 const CompletionCallback& callback) {
               DCHECK(io_state_ == STATE_NONE || io_state_ == STATE_DONE);
               DCHECK(callback_.is_null());
               DCHECK(!callback.is_null());

               int result = OK;
               io_state_ = STATE_READ_HEADERS;

               result = DoLoop(result);

               if (result == ERR_IO_PENDING)
                 callback_ = callback;

               return result > 0 ? OK : result;
             }

    In the second case, the IO completion callback will examine the
    return value from `DoLoop()`. If it is `net::ERR_IO_PENDING`, no
    further action will be taken, and the IO completion callback will be
    called again at some future point. If it is not
    `net::ERR_IO_PENDING`, that is a signal that the operation has
    completed, and the IO completion callback will call the appropriate
    consumer callback to notify the consumer that the operation has
    completed. Note that it is important that this callback be done
    from the IO completion callback and not from `DoLoop()` or a
    `DoLoop()` callee, both to support the sync/async error return
    (DoLoop and its callees don't know the difference) and to avoid
    consumer callbacks deleting the object out from under `DoLoop()`.
    Example: 

             void HttpStreamParser::OnIOComplete(int result) {
               result = DoLoop(result);

               if (result != ERR_IO_PENDING && !callback_.is_null())
                 base::ResetAndReturn(&callback_).Run(result);
             }
    
*   The DoLoop pattern has no concept of different events arriving for
    a single state; each state, if waiting, is waiting for one
    particular event, and when `DoLoop()` is invoked when the machine is
    in that state, it will handle that event. This reflects the
    single-threaded model for operations spawned by the state machine.

Public class methods generally have very little processing, primarily wrapping 
`DoLoop()`. For `DoLoop()` entry this involves setting the `next_state_`
variable, and possibly making copies of arguments into class members. For
`DoLoop()` exit, it involves inspecting the return and passing it back to
the caller, and in the asynchronous case, saving any passed completion callback
for executing by a future subsidiary IO completion (see above example). 

This idiom allows synchronous and asynchronous logic to be written in
the same fashion; it's all just state transition handling. For mostly
linear state diagrams, the handling code can be very easy to
comprehend, as such code is usually written linearly (in different
handling functions) in the order it's executed. 

For examples of this idiom, see

* [HttpStreamParser::DoLoop](https://code.google.com/p/chromium/codesearch#chromium/src/net/http/http_stream_parser.cc&q=HttpStreamParser::DoLoop&sq=package:chromium).
* [HttpNetworkTransaction::DoLoop](https://code.google.com/p/chromium/codesearch#chromium/src/net/http/http_network_transaction.cc&q=HttpNetworkTransaction::DoLoop&sq=package:chromium)

[net_error_list.h]: https://chromium.googlesource.com/chromium/src/+/master/net/base/net_error_list.h#1
