/*
 * Copyright (c) Likewise Software.  All rights Reserved.
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the license, or (at
 * your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
 * General Public License for more details.  You should have received a copy
 * of the GNU Lesser General Public License along with this program.  If
 * not, see <http://www.gnu.org/licenses/>.
 *
 * LIKEWISE SOFTWARE MAKES THIS SOFTWARE AVAILABLE UNDER OTHER LICENSING
 * TERMS AS WELL.  IF YOU HAVE ENTERED INTO A SEPARATE LICENSE AGREEMENT
 * WITH LIKEWISE SOFTWARE, THEN YOU MAY ELECT TO USE THE SOFTWARE UNDER THE
 * TERMS OF THAT SOFTWARE LICENSE AGREEMENT INSTEAD OF THE TERMS OF THE GNU
 * LESSER GENERAL PUBLIC LICENSE, NOTWITHSTANDING THE ABOVE NOTICE.  IF YOU
 * HAVE QUESTIONS, OR WISH TO REQUEST A COPY OF THE ALTERNATE LICENSING
 * TERMS OFFERED BY LIKEWISE SOFTWARE, PLEASE CONTACT LIKEWISE SOFTWARE AT
 * license@likewisesoftware.com
 */

/*
 * Module Name:
 *
 *        fsd-guide.doxy
 *
 * Abstract:
 *
 *        File system driver guide
 *
 * Authors: Brian Koropoff (bkoropoff@likewise.com)
 *
 */

/**
@page fsd-async Asynchronous Operation

@section Asynchronous Completion

When a driver receives an IRP, it may opt to complete it immediately
by carrying out the operation, setting output parameters, and
returning @a LW_STATUS_SUCCESS or an approriate error status directly
from the driver dispatch function.  This is referred to as
<b>synchronous completion</b>.  There are many cases where synchronous
completion is appropriate.  For example, the operation may fail due to
an access violation, or the requested data may already be present in a
cache.  In general, the dispatch function may perform a reasonable,
constant-bounded amount of work in order to fulfill the request.

If the driver cannot complete the IRP immediately, it <b>must not</b>
block indefinitely within the dispatch function.  For example,
performing network or disk I/O can, in the general case, incur
arbitrarily long delays.  In these instances, the driver is obligated
to complete the operation <b>asynchronously</b>.

The driver may mark the IRP as <b>pending</b> completion with
#IoIrpMarkPending().  Note that this function requires a cancellation
callback to be provided, the details of which are discussed below.

Once the IRP has been marked pending, the driver dispatch function
<b>must</b> arrange for the operation to be carried out in the
background.  Ideally, the underlying medium (e.g. network, block
storage device) will also support asynchronous operation, allowing the
request to be passed to it immediately.  Failing that, a generally
applicable technique is to pass the IRP to a worker thread queue which
can carry out any underlying synchronous operation out-of-band from
the original dispatch function.

After making appropriate arrangements for the operation to be carried
out in the background, the driver dispatch function <b>must</b> return
@a LW_STATUS_PENDING.  When the operation is complete, output
parameters should be set as usual.  In particular, the @a Status field
of IRP::IoStatusBlock must be set for all operations.  The IRP can
then be declared complete by invoking #IoIrpComplete().  Completion
may take place in an arbitrary thread.  It is safe for completion to
occur before the driver dispatch function has returned, as long as
#IoIrpMarkPending() was called first.

@section Cancellation

Calling applications may attempt to cancel an operation before it has
completed if the result is no longer desired.  For example, a file
server may cancel outstanding read requests if the client that
initiated them has already disconnected.

When an IRP is canceled, the cancellation function provided to
#IoIrpMarkPending() will be invoked.  This is guaranteed to occur only
after the driver dispatch function has returned.  The cancellation
function must arrange for the operation to be completed as quickly as
possible, up to and including aborting it entirely.  In this case, it
should be completed with @a LW_STATUS_CANCELLED as the result.

The cancellation function must not call #IoIrpComplete() directly.
This restriction may be lifted at a later date.

**/
