You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by jp...@apache.org on 2015/11/03 07:09:52 UTC

[16/51] trafficserver git commit: Documentation reorganization

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/io/cache-api.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/io/cache-api.en.rst b/doc/developer-guide/plugins/io/cache-api.en.rst
new file mode 100644
index 0000000..fc2f659
--- /dev/null
+++ b/doc/developer-guide/plugins/io/cache-api.en.rst
@@ -0,0 +1,167 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../../../common.defs
+
+.. _developer-plugins-io-cache-api:
+
+Cache API
+*********
+
+.. toctree::
+   :maxdepth: 2
+
+The cache API enables plugins to read, write, and remove objects in the
+Traffic Server cache. All cache APIs are keyed by an object called an
+``TSCacheKey``; cache keys are created via ``TSCacheKeyCreate``; keys
+are destroyed via ``TSCacheKeyDestroy``. Use ``TSCacheKeyDigestSet`` to
+set the hash of the cache key.
+
+Note that the cache APIs differentiate between HTTP data and plugin
+data. The cache APIs do not allow you to write HTTP docs in the cache;
+you can only write plugin-specific data (a specific type of data that
+differs from the HTTP type).
+
+**Example:**
+
+.. code-block:: c
+
+        const unsigned char *key_name = "example key name";
+
+        TSCacheKey key;
+        TSCacheKeyCreate (&key);
+        TSCacheKeyDigestSet (key, (unsigned char *) key_name , strlen(key_name));
+        TSCacheKeyDestroy (key);
+
+Cache Reads
+===========
+
+``TSCacheRead`` does not really read - it is used for lookups (see the
+sample Protocol plugin). Possible callback events include:
+
+-  ``TS_EVENT_CACHE_OPEN_READ`` - indicates the lookup was successful.
+   The data passed back along with this event is a cache vconnection
+   that can be used to initiate a read on this keyed data.
+
+-  ``TS_EVENT_CACHE_OPEN_READ_FAILED`` - indicates the lookup was
+   unsuccessful. Reasons for this event could be that another
+   continuation is writing to that cache location, or the cache key
+   doesn't refer to a cached resource. Data payload for this event
+   indicates the possible reason the read failed (``TSCacheError``).
+
+
+Cache Writes
+============
+
+Use ``TSCacheWrite`` to write to a cache (see the :ref:`sample Protocol
+plugin <about-the-sample-protocol>`). Possible
+callback events include:
+
+-  ``TS_EVENT_CACHE_WRITE_READ`` - indicates the lookup was successful.
+   The data passed back along with this event is a cache vconnection
+   that can be used to initiate a cache write.
+
+-  ``TS_EVENT_CACHE_OPEN_WRITE_FAILED`` - event returned when another
+   continuation is currently writing to this location in the cache. Data
+   payload for this event indicates the possible reason for the write
+   failing (``TSCacheError``).
+
+
+Cache Removes
+=============
+
+Use ``TSCacheRemove`` to remove items from the cache. Possible callback
+events include:
+
+-  ``TS_EVENT_CACHE_REMOVE`` - the item was removed. There is no data
+   payload for this event.
+
+-  ``TS_EVENT_CACHE_REMOVE_FAILED`` - indicates the cache was unable to
+   remove the item identified by the cache key. ``TSCacheError`` data
+   indicates why the remove failed.
+
+
+Errors
+======
+
+Errors pertaining to the failure of various cache operations are
+indicated by ``TSCacheError`` (enumeration). They are as follows:
+
+-  ``TS_CACHE_ERROR_NO_DOC`` - the key does not match a cached resource
+
+-  ``TS_CACHE_ERROR_DOC_BUSY`` - e.g, another continuation could be
+   writing to the cache location
+
+-  ``TS_CACHE_ERROR_NOT_READY`` - the cache is not ready
+
+
+Example
+=======
+
+In the example below, suppose there is a cache hit and the cache returns
+a vconnection that enables you to read the document from cache. To do
+this, you need to prepare a buffer (``cache_bufp``) to hold the
+document; meanwhile, use ``TSVConnCachedObjectSizeGet`` to find out the
+actual size of the document (``content_length``). Then, issue
+``TSVConnRead`` to read the document with the total data length required
+as ``content_length``. Assume the following data:
+
+.. code-block:: c
+
+        TSIOBuffer       cache_bufp = TSIOBufferCreate ();
+        TSIOBufferReader cache_readerp = TSIOBufferReaderAlloc (out_bufp);
+        TSVConn          cache_vconnp = NULL;
+        TSVIO            cache_vio = NULL;
+        int               content_length = 0;
+
+In the ``TS_CACHE_OPEN_READ`` handler:
+
+.. code-block:: c
+
+    cache_vconnp = (TSVConn) data;
+        TSVConnCachedObjectSizeGet (cache_vconnp, &content_length);
+        cache_vio = TSVConnRead (cache_vconn, contp, cache_bufp, content_length);
+
+In the ``TS_EVENT_VCONN_READ_READY`` handler:
+
+.. code-block:: c
+
+    (usual VCONN_READ_READY handler logic)
+    int nbytes = TSVIONBytesGet (cache_vio);
+    int ntodo  = TSVIONTodoGet (cache_vio);
+    int ndone  = TSVIONDoneGet (cache_vio);
+    (consume data in cache_bufp)
+    TSVIOReenable (cache_vio);
+
+Do not try to get continuations or VIOs from ``TSVConn`` objects for
+cache vconnections. Also note that the following APIs can only be used
+on transformation vconnections and must not be used on cache
+vconnections or net vconnections:
+
+-  ``TSVConnWriteVIOGet``
+
+-  ``TSVConnReadVIOGet``
+
+-  ``TSVConnClosedGet``
+
+APIs such as ``TSVConnRead``, ``TSVConnWrite``, ``TSVConnClose``,
+``TSVConnAbort``, and ``TSVConnShutdown`` can be used on any kind of
+vconnections.
+
+When you are finished:
+
+``TSCacheKeyDestroy (key);``

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/io/index.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/io/index.en.rst b/doc/developer-guide/plugins/io/index.en.rst
new file mode 100644
index 0000000..6fc47cd
--- /dev/null
+++ b/doc/developer-guide/plugins/io/index.en.rst
@@ -0,0 +1,197 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../../../common.defs
+
+.. _developer-plugins-io:
+
+IO
+**
+
+This chapter contains the following sections:
+
+.. toctree::
+   :maxdepth: 2
+
+   net-vconnections.en
+   transformations.en
+   vios.en
+   io-buffers.en
+   cache-api.en
+
+.. _sdk-vconnections:
+
+Vconnections
+============
+
+A User's Perspective
+--------------------
+
+To use a vconnection, a user must first get a handle to one. This is
+usually accomplished by having it handed to the user; the user may also
+simply issue a call that creates a vconnection (such as
+``TSNetConnect)``. In the case of transform plugins, the plugin creates
+a transformation vconnection viav ``TSTransformCreate`` and then
+accesses the output vconnection using ``TSTransformOutputVConnGet``.
+
+After getting a handle to a vconnection, the user can then issue a read
+or write call. It's important to note that not all vconnections support
+both reading and writing - as of yet, there has not been a need to query
+a vconnection about whether it can perform a read or write operation.
+That ability should be obvious from context.
+
+To issue a read or write operation, a user calls ``TSVConnRead`` or
+``TSVConnWrite``. These two operations both return ``VIO (TSVIO)``. The
+VIO describes the operation being performed and how much progress has
+been made. Transform plugins initiate output to the downstream
+vconnection by calling ``TSVConnWrite``.
+
+A vconnection read or write operation is different from a normal UNIX
+``read(2)`` or ``write(2)`` operation. Specifically, the vconnection
+operation can specify more data to be read or written than exists in the
+buffer handed to the operation. For example, it's typical to issue a
+read for ``INT64_MAX`` (9 quintillion) bytes from a network vconnection
+in order to read all the data from the network connection until the end
+of stream is reached. This contrasts with the usual UNIX fashion of
+issuing repeated calls to ``read(2)`` until one of the calls finally
+returns ``0`` to indicate the end of stream was reached (indeed, the
+underlying implementation of vconnections on UNIX still does issue those
+calls to ``read(2)``, but the interface does not expose that detail).
+
+At most, a given vconnection can have one read operation and one write
+operation being performed on it. This is restricted both by design and
+common sense: if two write operations were performed on a single
+vconnection, then the user would not be able to specify which should
+occur first and the output would occur in an intermingled fashion. Note
+that both a read operation and a write operation can happen on a single
+vconnection at the same time; the restriction is for more than one
+operation of the same type.
+
+One obvious issue is that the buffer passed to ``TSVConnRead`` and
+``TSVConnWrite`` won't be large enough - there is no reasonable way to
+make a buffer that can hold ``INT64_MAX`` (9 quintillion) bytes! The
+secret is that vconnections engage in a protocol whereby they signal to
+the user (via the continuation passed to ``TSVConnRead`` and
+``TSVConnWrite``) that they have emptied the buffers passed to them and
+are ready for more data. When this occurs, it is up to the user to add
+more data to the buffers (or wait for more data to be added) and then
+wake up the vconnection by calling ``TSVIOReenable`` on the VIO
+describing the operation. ``TSVIOReenable`` specifies that the buffer
+for the operation has been modified and that the vconnection should
+reexamine it to see if it can make further progress.
+
+The null transform plugin provides an example of how this is done. Below
+is a prototype for ``TSVConnWrite``:
+
+.. code-block:: c
+
+     TSVIO TSVConnWrite (TSVConn connp, TSCont contp, TSIOBufferReader readerp, int nbytes)
+
+The ``connp`` is the vconnection the user is writing to and ``contp`` is
+the "user" - i.e., the continuation that ``connp`` calls back when it
+has emptied its buffer and is ready for more data.
+
+The call made in the null transform plugin is:
+
+.. code-block:: c
+
+      TSVConnWrite (output_conn, contp, data->output_reader, TSVIONBytesGet (input_vio));
+
+In the example above, ``contp`` is the transformation vconnection that
+is writing to the output vconnection. The number of bytes to be written
+is obtained from ``input_vio`` by ``TSVIONBytesGet``.
+
+When a vconnection calls back its user to indicate that it wants more
+data (or when some other condition has occurred), it issues a call to
+``TSContCall``. It passes the ``TSVIO`` describing the operation as the
+data parameter, and one of the values below as the event parameter.
+
+``TS_EVENT_ERROR``
+    Indicates an error has occurred on the vconnection. This will happen
+    for network IO if the underlying ``read(2)`` or ``write(2)`` call
+    returns an error.
+
+``TS_EVENT_VCONN_READ_READY``
+    The vconnection has placed data in the buffer passed to an
+    ``TSVConnRead`` operation and it would like to do more IO, but the
+    buffer is now full. When the user consumes the data from the buffer,
+    this should re-enable the VIO so it indicates to the vconnection
+    that the buffer has been modified.
+
+``TS_EVENT_VCONN_WRITE_READY``
+    The vconnection has removed data from the buffer passed to an
+    ``TSVConnWrite`` operation and it would like to do more IO, but the
+    buffer does not have enough data in it. When placing more data in
+    the buffer, the user should re-enable the VIO so it indicates to the
+    vconnection that the buffer has been modified.
+
+``TS_EVENT_VCONN_READ_COMPLETE``
+    The vconnection has read all the bytes specified by an
+    ``TSVConnRead`` operation. The vconnection can now be used to
+    initiate a new IO operation.
+
+``TS_EVENT_VCONN_WRITE_COMPLETE``
+    The vconnection has written all the bytes specified by an
+    ``TSVConnWrite`` operation and can now be used to initiate a new IO
+    operation.
+
+``TS_EVENT_VCONN_EOS``
+    An attempt was made to read past the end of the stream of bytes
+    during the handling of an ``TSVConnRead`` operation. This event
+    occurs when the number of bytes available for reading from a
+    vconnection is less than the number of bytes the user specifies
+    should be read from the vconnection in a call to ``TSVConnRead``. A
+    common case where this occurs is when the user specifies that
+    ``INT64_MAX`` bytes are to be read from a network connection.
+
+For example: the null transform plugin's transformation receives
+``TS_EVENT_VCONN_WRITE_READY`` and ``TS_EVENT_VCONN_WRITE_COMPLETE``
+events from the downstream vconnection as a result of the call to
+``TSVConnWrite``.
+
+After using a vconnection, the user must call ``TSVConnClose`` or
+``TSVConnAbort``. While both calls indicate that the vconnection can
+destroy itself, ``TSVConnAbort`` should be used when the connection is
+being closed abnormally. After a call to ``TSVConnClose`` or
+``TSVConnAbort``, the user will not be called back by the vconnection
+again.
+
+Sometimes it's desirable to simply close down the write portion of a
+connection while keeping the read portion open. This can be accomplished
+via the ``TSVConnShutdown`` function, which shuts down either the read
+or write portion of a vconnection. *Shutdown* means that the vconnection
+will no longer call back the user with events for the portion of the
+connection that was shut down. For example: if the user shuts down the
+write portion of a connection, then the ``TS_EVENT_VCONN_WRITE_READY``
+or ``TS_EVENT_VCONN_WRITE_COMPLETE`` events will not be produced. In the
+null transform plugin, the write operation is shut down with a call to
+``TSVConnShutdown``. To learn how vconnections are used in
+transformation plugins, see :ref:`Writing Content Transform
+Plugins <WritingContentTransformPlugin>`.
+
+The vconnection functions are listed below:
+
+-  :c:func:`TSVConnAbort`
+-  :c:func:`TSVConnClose`
+-  :c:func:`TSVConnClosedGet`
+-  :c:func:`TSVConnRead`
+-  :c:func:`TSVConnReadVIOGet`
+-  :c:func:`TSVConnShutdown`
+-  :c:func:`TSVConnWrite`
+-  :c:func:`TSVConnWriteVIOGet`
+
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/io/io-buffers.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/io/io-buffers.en.rst b/doc/developer-guide/plugins/io/io-buffers.en.rst
new file mode 100644
index 0000000..d7d199d
--- /dev/null
+++ b/doc/developer-guide/plugins/io/io-buffers.en.rst
@@ -0,0 +1,56 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../../../common.defs
+
+.. _developer-plugins-io-buffers:
+
+IO Buffers
+**********
+
+The IO buffer data structure is the building block of the vconnection
+abstraction. An **IO buffer** (``TSIOBuffer``) is composed of a list of
+buffer blocks that point to buffer data. Both the buffer block
+(``TSIOBufferBlock``) and buffer data (``TSIOBufferData``) data
+structures are reference-counted, so they can reside in multiple buffers
+at the same time. This makes it extremely efficient to copy data from
+one IO buffer to another via ``TSIOBufferCopy``, since Traffic Server
+must only copy pointers and adjust reference counts appropriately (and
+doesn't actually copy any data).
+
+The IO buffer abstraction provides for a single writer and multiple
+readers. In order for the readers to have no knowledge of each other,
+they manipulate IO buffers through the ``TSIOBufferReader`` data
+structure. Since only a single writer is allowed, there is no
+corresponding ``TSIOBufferWriter`` data structure. The writer simply
+modifies the IO buffer directly. To see an example that illustrates how
+to use IOBuffers, refer to the sample code in the description of
+:c:func:`TSIOBufferBlockReadStart`.
+
+Additional information about IO buffer functions:
+
+-  The ``TSIOBufferReader`` data structure tracks how much data in
+   ``TSIOBuffer`` has been read. It has an offset number of bytes that
+   is the current start point of a particular buffer reader (for every
+   read operation on an ``TSIOBuffer``, you must allocate an
+   ``TSIOBufferReader``).
+
+-  Bytes that have already been read may not necessarily be freed within
+   the ``TSIOBuffer``. To consume bytes that have been read, you must
+   call ``TSIOBufferConsume``.
+
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/io/net-vconnections.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/io/net-vconnections.en.rst b/doc/developer-guide/plugins/io/net-vconnections.en.rst
new file mode 100644
index 0000000..744c960
--- /dev/null
+++ b/doc/developer-guide/plugins/io/net-vconnections.en.rst
@@ -0,0 +1,35 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../../../common.defs
+
+.. _developer-plugins-io-net-vconnections:
+
+Net Vconnections
+****************
+
+A **network vconnection** (or *netvconnection*) is a wrapper
+around a TCP socket that enables the socket to work within the Traffic
+Server vconnection framework. See
+:ref:`vconnections <sdk-vconnections>` for more information about
+the Traffic Server abstraction for doing asynchronous IO.
+
+The netvconnection functions are listed below:
+
+-  [dox 'TSNetAccept'] in [dox "TSNetAccept" :src\_file]
+-  [dox %TSNetConnect%] in [dox :src\_file]
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/io/transformations.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/io/transformations.en.rst b/doc/developer-guide/plugins/io/transformations.en.rst
new file mode 100644
index 0000000..947e6f3
--- /dev/null
+++ b/doc/developer-guide/plugins/io/transformations.en.rst
@@ -0,0 +1,183 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../../../common.defs
+
+.. _developer-plugins-io-transformations:
+
+Transformations
+***************
+
+Vconnection Implementor's View
+==============================
+
+A VConnection implementor writes only transformations. All other
+VConnections (net VConnections and cache VConnections) are implemented
+in iocore. As mentioned earlier, a given vconnection can have a maximum
+of one read operation and one write operation being performed on it. The
+vconnection user gets information about the operation being performed by
+examining the VIO returned by a call to ``TSVConnRead`` or
+``TSVConnWrite``. The implementor, in turn, gets a handle on the VIO
+operation by examining the VIO returned by ``TSVConnReadVIOGet`` or
+``TSVConnWriteVIOGet`` (recall that every vconnection created through
+the Traffic Server API has an associated read VIO and write VIO, even if
+it only supports reading or writing).
+
+For example, the null transform plugin's transformation examines the
+input VIO by calling:
+
+.. code-block:: c
+
+     input_vio = TSVConnWriteVIOGet (contp);
+
+where ``contp`` is the transformation.
+
+A vconnection is a continuation. This means it has a handler function
+that is run when an event is sent to it, or more accurately, when an
+event that was sent to it is received. It is the handler function's job
+to examine the event, the current state of its read VIO and write VIO,
+and any other internal state the vconnection might have and potentially
+make some progress on the IO operations.
+
+It is common for the handler function for all vconnections to look
+similar. Their basic form looks something like the code fragment below:
+
+.. code-block:: c
+
+    int
+    vconnection_handler (TSCont contp, TSEvent event, void *edata)
+    {
+    if (TSVConnClosedGet (contp)) {
+            /* Destroy any vconnection specific data here. */
+            TSContDestroy (contp);
+            return 0;
+       } else {
+            /* Handle the incoming event */
+       }
+    }
+
+This code fragment basically shows that many vconnections simply want to
+destroy themselves when they are closed. However, the situation might
+also require the vconnection to do some cleanup processing - which is
+why ``TSVConnClose`` does not simply just destroy the vconnection.
+
+Vconnections are state machines that are animated by the events they
+receive. An event is sent to the vconnection whenever an
+``TSVConnRead``, ``TSVConnWrite``, ``TSVConnClose``,
+``TSVConnShutdown``, or ``TSVIOReenable`` call is performed.
+``TSVIOReenable`` indirectly references the vconnection through a
+back-pointer in the VIO structure to the vconnection. The vconnection
+itself only knows which call was performed by examining its state and
+the state of its VIOs. For example, when ``TSVConnClose`` is called, the
+vconnection is sent an immediate event (``TS_EVENT_IMMEDIATE``). For
+every event the vconnection receives, it needs to check its closed flag
+to see if it has been closed. Similarly, when ``TSVIOReenable`` is
+called, the vconnection is sent an immediate event. For every event the
+vconnection receives, it must check its VIOs to see if the buffers have
+been modified to a state in which it can continue processing one of its
+operations.
+
+Finally, a vconnection is likely the user of other vconnections. It also
+receives events as the user of these other vconnections. When it
+receives such an event, like ``TS_EVENT_VCONN_WRITE_READY``, it might
+just enable another vconnection that's writing into the buffer used by
+the vconnection reading from it. The above description is merely
+intended to give the overall idea for what a vconnection needs to do.
+
+Transformation VConnection
+--------------------------
+
+A :ref:`transformation <transformations>` is
+a specific type of vconnection. It supports a subset of the vconnection
+functionality that enables one or more transformations to be chained
+together. A transformation sits as a bottleneck between an input data
+source and an output data sink, which enables it to view and modify all
+the data passing through it. Alternatively, some transformations simply
+scan the data and pass it on. A common transformation is one that
+compresses data in some manner.
+
+A transformation can modify either the data stream being sent *to* an
+HTTP client (e.g. the document) or the data stream being sent *from* an
+HTTP client (e.g. post data). To do this, the transformation should hook
+on to one of the following hooks:
+
+-  ``TS_HTTP_REQUEST_TRANSFORM_HOOK``
+
+-  ``TS_HTTP_RESPONSE_TRANSFORM_HOOK``
+
+Note that because a transformation is intimately associated with a given
+transaction, it is only possible to add the hook to the transaction
+hooks - not to the global or session hooks. Transformations reside in a
+chain, so their ordering is quite easily determined: transformations
+that add themselves to the chain are simply appended to it.
+
+Data is passed in to the transformation by initiating a vconnection
+write operation on the transformation. As a consequence of this design,
+a transformation must support the vconnection write operation. In other
+words, your transformation must expect an upstream vconnection to write
+data to it. The transformation has to read the data, consume it, and
+tell the upstream vconnection it is finished by sending it an
+``TS_EVENT_WRITE_COMPLETE`` event. Transformations cannot send the
+``TS_EVENT_VCONN_WRITE_COMPLETE`` event to the upstream vconnection
+unless they are finished consuming all incoming data. If
+``TS_EVENT_VCONN_WRITE_COMPLETE`` is sent prematurely, then certain
+internal Traffic Server data structures will not be deallocated, thereby
+causing a memory leak.
+
+Here's how to make sure that all incoming data is consumed:
+
+-  After reading or copying data, make sure that you consume the data
+   and increase the value of ndone for the input VIO, as in the
+   following example taken from ``null-transform.c``:
+
+   .. code-block:: c
+
+       TSIOBufferCopy (TSVIOBufferGet (data->output_vio),
+       TSVIOReaderGet (input_vio), towrite, 0);
+       /* Tell the read buffer that we have read the data and are no longer interested in it. */
+       TSIOBufferReaderConsume (TSVIOReaderGet (input_vio), towrite);
+       /* Modify the input VIO to reflect how much has been read.*/
+       TSVIONDoneSet (input_vio, TSVIONDoneGet (input_vio) + towrite);
+
+-  Before sending ``TS_EVENT_VCONN_WRITE_COMPLETE``, your transformation
+   should check the number of bytes remaining in the upstream
+   vconnection's write VIO (input VIO) using the function
+   ``TSVIONTodoGet`` (``input_vio``). This value should go to zero when
+   all of the upstream data is consumed
+   (``TSVIONTodoGet = nbytes - ndone``). Do not send
+   ``TS_EVENT_VCONN_WRITE_COMPLETE`` events if ``TSVIONTodoGet`` is
+   greater than zero.
+-  The transformation passes data out of itself by using the output
+   vconnection retrieved by ``TSTransformOutputVConnGet``. Immediately
+   before Traffic Server initiates the write operation (which inputs
+   data into the transformation), it sets the output vconnection either
+   to the next transformation in the chain of transformations or to a
+   special terminating transformation (if it's the last transformation
+   in the chain). Since the transformation is handed ownership of the
+   output vconnection, it must close it at some point in order for it to
+   be deallocated.
+-  All of the transformations in a transformation chain share the
+   transaction's mutex. This small restriction (enforced by
+   ``TSTransformCreate``) removes many of the locking complications of
+   implementing general vconnections. For example, a transformation does
+   not have to grab its write VIO mutex before accessing its write VIO
+   because it knows it already holds the mutex.
+
+The transformation functions are: \*
+:c:func:`TSTransformCreate`
+\*
+:c:func:`TSTransformOutputVConnGet`

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/io/vios.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/io/vios.en.rst b/doc/developer-guide/plugins/io/vios.en.rst
new file mode 100644
index 0000000..8048c78
--- /dev/null
+++ b/doc/developer-guide/plugins/io/vios.en.rst
@@ -0,0 +1,62 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../../../common.defs
+
+.. _developer-plugins-io-vios:
+
+VIOs
+****
+
+A **VIO**, or **virtual IO**, is a description of an IO operation that's
+currently in progress. The VIO data structure is used by vconnection
+users to determine how much progress has been made on a particular IO
+operation and to re-enable an IO operation when it stalls due to buffer
+space issues. VIOs are used by vconnection implementors to determine the
+buffer for an IO operation, how much work to do on the IO operation, and
+which continuation to call back when progress on the IO operation is
+made.
+
+The ``TSVIO`` data structure itself is opaque, but it could be defined
+as follows:
+
+.. code-block:: c
+
+    typedef struct {
+        TSCont continuation;
+        TSVConn vconnection;
+        TSIOBufferReader reader;
+        TSMutex mutex;
+        int nbytes;
+        int ndone;
+    } *TSVIO;
+
+The VIO functions below access and modify various parts of the data
+structure.
+
+-  :c:func:`TSVIOBufferGet`
+-  :c:func:`TSVIOVConnGet`
+-  :c:func:`TSVIOContGet`
+-  :c:func:`TSVIOMutexGet`
+-  :c:func:`TSVIONBytesGet`
+-  :c:func:`TSVIONBytesSet`
+-  :c:func:`TSVIONDoneGet`
+-  :c:func:`TSVIONDoneSet`
+-  :c:func:`TSVIONTodoGet`
+-  :c:func:`TSVIOReaderGet`
+-  :c:func:`TSVIOReenable`
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/mutexes.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/mutexes.en.rst b/doc/developer-guide/plugins/mutexes.en.rst
new file mode 100644
index 0000000..2c71e8f
--- /dev/null
+++ b/doc/developer-guide/plugins/mutexes.en.rst
@@ -0,0 +1,397 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../../common.defs
+
+.. _developer-plugins-mutexes:
+
+Mutexes
+*******
+
+.. toctree::
+   :maxdepth: 1
+
+A *mutex* is the basic synchronization method used within Traffic
+Server to protect data from simultaneous access by multiple threads. A
+mutex acts as a lock that protects data in one program thread from being
+accessed by another thread.
+
+The Traffic Server API provides two functions that attempt to access and
+lock the data: :c:func:`TSMutexLockTry` and :c:func:`TSMutexLock`.
+``TSMutexLock`` is a blocking call - if you use it, you can slow
+Traffic Server performance because transaction processing pauses until
+the mutex is unlocked. It should be used only on threads created by the
+plugin ``TSContThreadCreate``. Never use it on a continuation handler
+called back by the Cache, Net, or Event Processor. Even if the critical
+section is very small, do not use it. If you need to update a flag, then
+set a variable and/or use atomic operations. If :c:func:`TSMutexLock` is used
+in any case other than the one recommended above, then the result will
+be a serious performance impact.
+
+``TSMutexLockTry``, on the other hand, attempts to lock the mutex
+only if it is unlocked (i.e., not being used by another thread). It
+should be used in all cases other than the above mentioned
+``TSMutexLock`` case. If the ``TSMutexLockTry`` attempt fails, then you
+can schedule a future attempt (which must be at least 10 milliseconds
+later).
+
+In general, you should use ``TSMutexLockTry`` instead of
+``TSMutexLock``.
+
+-  ``TSMutexLockTry`` is required if you are tying to lock Traffic
+   Server internal or system resources (such as the network, cache,
+   event processor, HTTP state machines, and IO buffers).
+
+-  ``TSMutexLockTry`` is required if you are making any blocking calls
+   (such as network, cache, or file IO calls).
+
+-  ``TSMutexLock`` might not be necessary if you are not making
+   blocking calls and if you are only accessing local resources.
+
+The Traffic Server API uses the ``TSMutex`` type for a mutex. There are
+two typical uses of mutex. One use is for locking global data or data
+shared by various continuations. The other typical usage is for locking
+data associated with a continuation (i.e., data that might be accessed
+by other continuations).
+
+Locking Global Data
+===================
+
+The :ref:`blacklist-1.c` sample plugin implements a mutex that locks global
+data. The blacklist plugin reads its blacklisted sites from a
+configuration file; file read operations are protected by a mutex
+created in :c:func:`TSPluginInit`. The :ref:`blacklist-1.c` code uses
+:c:func:`TSMutexLockTry` instead of :c:func:`TSMutexLock`. For more detailed
+information, see the :ref:`blacklist-1.c` code;
+start by looking at the :c:func:`TSPluginInit` function.
+
+General guidelines for locking shared data are as follows:
+
+1. Create a mutex for the shared data with
+   :c:func:`TSMutexCreate`.
+
+2. Whenever you need to read or modify this data, first lock it by
+   calling
+   :c:func:`TSMutexLockTry`;
+   then read or modify the data.
+
+3. When you are done with the data, unlock it with
+   :c:func:`TSMutexUnlock`.
+   If you are unlocking data accessed during the processing of an HTTP
+   transaction, then you must unlock it before calling
+   :c:func:`TSHttpTxnReenable`.
+
+Protecting a Continuation's Data
+================================
+
+You must create a mutex to protect a continuation's data if it might be
+accessed by other continuations or processes. Here's how:
+
+1. | Create a mutex for the continuation using ``TSMutexCreate``.
+   | For example:
+
+   .. code-block:: c
+
+       TSMutex mutexp;
+       mutexp = TSMutexCreate ();
+
+2. | When you create the continuation, specify this mutex as the
+     continuation's mutex.
+   | For example:
+
+   .. code-block:: c
+
+       TSCont contp;
+       contp = TSContCreate (handler, mutexp);
+
+If any other functions want to access ``contp``'s data, then it is up to
+them to get ``contp``'s mutex (using, for example, ``TSContMutexGet``)
+to lock it. For usage, ssee the sample Protocol plugin.
+
+How to Associate a Continuation With Every HTTP Transaction
+===========================================================
+
+There could be several reasons why you'd want to create a continuation
+for each HTTP transaction that calls back your plugin.
+
+Some potential scenarios are listed below.
+
+-  You want to register hooks locally with the new continuation instead
+   of registering them globally to the continuation plugin.
+
+-  You want to store data specific to each HTTP transaction that you
+   might need to reuse across various hooks.
+
+-  You're using APIs (like ``TSHostLookup``) that will call back the
+   continuation with a certain event.
+
+How to Add the New Continuation
+===============================
+
+A typical way of adding the new continuation is by registering the
+plugin continuation to be called back by HTTP transactions globally when
+they reach ``TS_HTTP_TXN_START_HOOK``. Refer to the example below, which
+uses a transaction-specific continuation called ``txn_contp``.
+
+.. code-block:: c
+
+           void TSPluginInit(int argc, const char *argv[]) 
+           { 
+               /* Plugin continuation */ 
+               TSCont contp; 
+               if ((contp = TSContCreate (plugin_cont_handler, NULL)) == TS_ERROR_PTR) { 
+                   LOG_ERROR("TSContCreate"); 
+               } else { 
+                   if (TSHttpHookAdd (TS_HTTP_TXN_START_HOOK, contp) == TS_ERROR) { 
+                       LOG_ERROR("TSHttpHookAdd"); 
+                   } 
+               } 
+           }
+
+In the plugin continuation handler, create the new continuation
+``txn_contp`` and then register it to be called back at
+``TS_HTTP_TXN_CLOSE_HOOK``:
+
+.. code-block:: c
+
+           static int plugin_cont_handler(TSCont contp, TSEvent event, void *edata) 
+           { 
+               TSHttpTxn txnp = (TSHttpTxn)edata; 
+               TSCont txn_contp; 
+
+               switch (event) { 
+                   case TS_EVENT_HTTP_TXN_START: 
+                       /* Create the HTTP txn continuation */ 
+                       txn_contp = TSContCreate(txn_cont_handler, NULL); 
+
+                       /* Register txn_contp to be called back when txnp reaches TS_HTTP_TXN_CLOSE_HOOK */ 
+                       if (TSHttpTxnHookAdd (txnp, TS_HTTP_TXN_CLOSE_HOOK, txn_contp) == TS_ERROR) { 
+                           LOG_ERROR("TSHttpTxnHookAdd"); 
+                       } 
+
+                       break; 
+
+                   default: 
+                       TSAssert(!"Unexpected Event"); 
+                       break; 
+               } 
+
+               if (TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE) == TS_ERROR) { 
+                   LOG_ERROR("TSHttpTxnReenable"); 
+               } 
+
+               return 0; 
+           }
+
+Remember that the ``txn_contp`` handler must destory itself when the
+HTTP transaction is closed. If you forget to do this, then your plugin
+will have a memory leak.
+
+.. code-block:: c
+
+
+           static int txn_cont_handler(TSCont txn_contp, TSEvent event, void *edata) 
+           { 
+               TSHttpTxn txnp; 
+               switch (event) { 
+                   case TS_EVENT_HTTP_TXN_CLOSE: 
+                       txnp = (TSHttpTxn) edata; 
+                       TSContDestroy(txn_contp); 
+                       break; 
+
+                   default: 
+                       TSAssert(!"Unexpected Event"); 
+                       break; 
+               } 
+
+               if (TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE) == TS_ERROR) { 
+                   LOG_ERROR("TSHttpTxnReenable"); 
+               } 
+
+               return 0; 
+           }
+
+How to Store Data Specific to Each HTTP Transaction
+===================================================
+
+For the example above, store the data in the ``txn_contp`` data
+structure - this means that you'll create your own data structure. Now
+suppose you want to store the state of the HTTP transaction:
+
+.. code-block:: c
+
+       typedef struct { 
+             int state; 
+         } ContData;
+
+You need to allocate the memory and initialize this structure for each
+HTTP ``txnp``. You can do that in the plugin continuation handler when
+it is called back with ``TS_EVENT_HTTP_TXN_START``
+
+.. code-block:: c
+
+           static int plugin_cont_handler(TSCont contp, TSEvent event, void *edata) 
+           { 
+               TSHttpTxn txnp = (TSHttpTxn)edata; 
+               TSCont txn_contp; 
+               ContData *contData; 
+
+               switch (event) { 
+                   case TS_EVENT_HTTP_TXN_START: 
+                       /* Create the HTTP txn continuation */ 
+                       txn_contp = TSContCreate(txn_cont_handler, NULL); 
+
+                       /* Allocate and initialize the txn_contp data */ 
+                       contData = (ContData*) TSmalloc(sizeof(ContData)); 
+                       contData->state = 0; 
+                       if (TSContDataSet(txn_contp, contData) == TS_ERROR) { 
+                           LOG_ERROR("TSContDataSet"); 
+                       } 
+
+                       /* Register txn_contp to be called back when txnp reaches TS_HTTP_TXN_CLOSE_HOOK */ 
+                       if (TSHttpTxnHookAdd (txnp, TS_HTTP_TXN_CLOSE_HOOK, txn_contp) == TS_ERROR) { 
+                           LOG_ERROR("TSHttpTxnHookAdd"); 
+                       } 
+
+                       break; 
+
+                   default: 
+                       TSAssert(!"Unexpected Event"); 
+                       break; 
+               } 
+
+               if (TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE) == TS_ERROR) { 
+                   LOG_ERROR("TSHttpTxnReenable"); 
+               } 
+
+               return 0; 
+           }
+
+For accessing this data from anywhere, use TSContDataGet:
+
+.. code-block:: c
+
+           TSCont txn_contp; 
+           ContData *contData; 
+
+           contData = TSContDataGet(txn_contp); 
+           if (contData == TS_ERROR_PTR) { 
+               LOG_ERROR("TSContDataGet"); 
+           } 
+           contData->state = 1;
+
+Remember to free this memory before destroying the continuation:
+
+.. code-block:: c
+
+           static int txn_cont_handler(TSCont txn_contp, TSEvent event, void *edata) 
+           { 
+               TSHttpTxn txnp; 
+               ContData *contData; 
+               switch (event) { 
+                   case TS_EVENT_HTTP_TXN_CLOSE: 
+                       txnp = (TSHttpTxn) edata; 
+                       contData = TSContDataGet(txn_contp); 
+                       if (contData == TS_ERROR_PTR) { 
+                           LOG_ERROR("TSContDataGet"); 
+                       } else { 
+                           TSfree(contData); 
+                       } 
+                       TSContDestroy(txn_contp); 
+                       break; 
+
+                   default: 
+                       TSAssert(!"Unexpected Event"); 
+                       break; 
+               } 
+
+               if (TSHttpTxnReenable(txnp, TS_EVENT_HTTP_CONTINUE) == TS_ERROR) { 
+                   LOG_ERROR("TSHttpTxnReenable"); 
+               } 
+
+               return 0; 
+           }
+
+Using Locks
+===========
+
+You do not need to use locks when a continuation has registered itself
+to be called back by HTTP hooks and it only uses the HTTP APIs. In the
+example above, the continuation ``txn_contp`` has registered itself to
+be called back at HTTP hooks and it only uses the HTTP APIs. In this
+case only, it's safe to access data shared between ``txnp`` and
+``txn_contp`` without grabbing a lock. In the example above,
+``txn_contp`` is created with a ``NULL`` mutex. This works because the
+HTTP transaction ``txnp`` is the only one that will call back
+``txn_contp``, and you are guaranteed that ``txn_contp`` will be called
+back only one hook at a time. After processing is finished,
+``txn_contp`` will reenable ``txnp``.
+
+In all other cases, you should create a mutex with the continuation. In
+general, a lock is needed when you're using iocore APIs or any other API
+where ``txn_contp`` is scheduled to be called back by a processor (such
+as the cache processor, the DNS processor, etc.). This ensures that
+``txn_contp`` is called back sequentially and not simultaneously. In
+other words, you need to ensure that ``txn_contp`` will not be called
+back by both ``txnp`` and the cache processor at the same time, since
+this will result in a situation wherein you're executing two pieces of
+code in conflict.
+
+Special Case: Continuations Created for HTTP Transactions
+=========================================================
+
+If your plugin creates a new continuation for each HTTP transaction,
+then you probably don't need to create a new mutex for it because each
+HTTP transaction (``TSHttpTxn`` object) already has its own mutex.
+
+In the example below, it's not necessary to specify a mutex for the
+continuation created in ``txn_handler``:
+
+.. code-block:: c
+
+    static void
+    txn_handler (TSHttpTxn txnp, TSCont contp) {
+        TSCont newCont;
+        ....
+            newCont = TSContCreate (newCont_handler, NULL);
+        //It's not necessary to create a new mutex for newCont.
+
+        ...
+
+            TSHttpTxnReenable (txnp, TS_EVENT_HTTP_CONTINUE);
+    }
+
+   static int
+   test_plugin (TSCont contp, TSEvent event, void *edata) {
+       TSHttpTxn txnp = (TSHttpTxn) edata;
+
+       switch (event) {
+           case TS_EVENT_HTTP_READ_REQUEST_HDR:
+               txn_handler (txnp, contp);
+               return 0;
+           default:
+               break;
+       }
+       return 0;
+   }
+
+The mutex functions are listed below:
+
+-  :c:func:`TSMutexCreate`
+-  :c:func:`TSMutexLock`
+-  :c:func:`TSMutexLockTry`
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/new-protocol-plugins.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/new-protocol-plugins.en.rst b/doc/developer-guide/plugins/new-protocol-plugins.en.rst
new file mode 100644
index 0000000..b7150d6
--- /dev/null
+++ b/doc/developer-guide/plugins/new-protocol-plugins.en.rst
@@ -0,0 +1,373 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../../common.defs
+
+.. _developer-plugins-new-protocol-plugins:
+
+New Protocol Plugins
+********************
+
+.. toctree::
+   :maxdepth: 1
+
+The new protocol APIs enable you to extend Traffic Server to be a web
+proxy for any protocol. This chapter describes new protocol APIs and the
+plugins that support new protocols. It also provides a detailed review
+of code for a sample Protocol plugin that supports a very simple
+artificial HTTP-like protocol.
+
+.. _about-the-sample-protocol:
+
+About the Sample Protocol
+=========================
+
+The sample protocol enables a client to ask a server for a file. Clients
+send requests to a specific Traffic Server port (specified in
+:file:`plugin.config`); each request has the following structure::
+
+   server_name file_name
+
+Using the Protocol plugin, Traffic Server can accept these requests,
+parse them, and act as a proxy cache (i.e., request the file from the
+origin server on the client's behalf and store copies of response
+messages in cache). The Protocol plugin is a state machine that flows
+through the states illustrated in the :ref:`Sample Protocol State
+Diagram <SampleProtocolStDiag>`. This figure illustrates the steps
+that Traffic Server and the Protocol plugin go through in order to
+support the sample protocol.
+
+In more specific terms, Traffic Server and the Protocol plugin must:
+
+-  Listen for and accept client connections (on the accept port
+   specified in :file:`plugin.config`)
+
+-  Read incoming client requests
+
+-  Look up the requested content in the Traffic Server cache
+
+-  Serve content from cache if the request is a cache hit (this simple
+   example does not do freshness checking)
+
+-  Open a connection to the origin server if the request is a cache miss
+   (on the server port specified in :file:`plugin.config`)
+
+-  Forward the request to the origin server
+
+-  Receive the origin server response
+
+-  Cache the response and send it on to the client
+
+**Sample Protocol State Diagram**
+
+.. _SampleProtocolStDiag:
+
+.. figure:: ../static/images/sdk/Protocol_state_diagram.jpg
+   :alt: Sample Protocol State Diagram
+
+   Sample Protocol State Diagram
+
+Protocol Plugin Structure
+=========================
+
+To see how the Protocol plugin works, you need to understand some
+broader concepts. This section assumes you're familiar with the concepts
+of :term:`continuation`, Traffic Server's **asynchronous event model**, and
+basic Traffic Server **plugin structure**. If you are not familiar with
+these concepts, then you may want to begin with the
+:ref:`developer-plugins-getting-started` section.
+
+Continuations in the Protocol Plugin
+====================================
+
+The Protocol plugin creates a static continuation that is an **"accept"
+state machine** - that is, a state machine whose job is to accept client
+connections on the appropriate port. When Traffic Server accepts a net
+connection from a client on that port, the accept state machine is
+activated. It then creates a new continuation: a transaction state
+machine. The accept state machine creates one transaction state machine
+for each transaction (where a :term:`transaction` consists of a client
+request and Traffic Server's response). Each transaction state machine
+lives until the transaction completes; then it is destroyed. If the
+client's request for content is a cache miss, then a transaction state
+machine might need to open a connection to the origin server. This is
+illustrated in the :ref:`Protocol Plugin
+Overview <ProtocolPluginOverview>` diagram below.
+
+**Protocol Plugin Overview**
+
+.. _ProtocolPluginOverview:
+
+.. figure:: ../static/images/sdk/protocol_sm_big.jpg
+   :alt: Protocol Plugin Overview
+
+   Protocol Plugin Overview
+
+The first steps for writing the Protocol plugin are now clear: in
+``TSPluginInit``, you must create a continuation that listens for net
+connections on the client port specified in :file:`plugin.config` (this
+continuation is the accept state machine).
+
+Below is a summary of the continuations implemented for the Protocol
+plugin:
+
+-  An **accept state machine** that listens for client connections, and
+   then creates transaction state machines whenever Traffic Server
+   accepts a new client connection. The accept state machine lives as
+   long as Traffic Server is running.
+
+-  **Transaction state machines** that read client requests, process
+   them, and are then destroyed when the transaction is finished.
+
+Event Flow
+==========
+
+Implementing the rest of the Protocol plugin requires that you
+understand the flow of events during the course of a transaction. Unlike
+HTTP transaction plugins, this plugin must read data from network
+connections and then read/write data to the Traffic Server cache. This
+means that its continuations do not receive HTTP state machine events;
+they receive events from Traffic Server's processor subsystems. For
+example: the accept state machine is activated by an
+``TS_EVENT_NET_ACCEPT`` event from Traffic Server's Net Processor; the
+handler function for the accept state machine must therefore be able to
+handle that event.
+
+The transaction state machines are activated when the client connection
+receives incoming request data. The **Net Processor** notifies the
+transaction state machine of incoming data. The transaction state
+machine reads the data; when finished, it initiates a cache lookup of
+the requested file. When the cache lookup completes, the transaction
+state machine is activated by the Traffic Server **Cache Processor**.
+
+If the transaction state machine needs to open a connection to the
+origin server to fetch content (in the case of a cache miss), then the
+transaction state machine initiates a DNS lookup of the server name. The
+transaction state machine is activated by a DNS lookup event from the
+Traffic Server **Host Database Processor**. If the transaction must
+connect to the origin server, then the transaction state machine
+initiates a net connection and waits for an event from the Net
+Processor.
+
+**Protocol Plugin Flow of Events**
+
+.. _ProtocolPluginFlow:
+
+.. figure:: ../static/images/sdk/protocol_evt.jpg
+   :alt: Protocol Plugin Flow of Events
+
+   Protocol Plugin Flow of Events
+
+The flow of events is illustrated in the :ref:`Protocol Plugin Flow of
+Events <ProtocolPluginFlow>` diagram above. The thin straight lines
+show Net Processor event flow, the thin dashed lines represent Host
+Database event flow, and the thick dashed lines show Cache event flow.
+
+Notice that this flow of events is independent of the Protocol plugin's
+design (i.e., whether you build **accept** or **transaction** state
+machines). Any plugin that supports network connections uses the net
+vconnection interfaces (``TSNetAccept``, ``TSNetConnect``) and thus
+receives events from the Net Processor. Any plugin that performs cache
+lookups or cache writes uses ``TSCacheRead``, ``TSCacheWrite``,
+``TSVConnRead``, and ``TSVConnWrite`` and thus receives events from the
+Cache Processor and Traffic Server event system. Similarly, any plugin
+that does DNS lookups receives events from the Host Database Processor.
+
+.. _one-way-to-implement-a-transaction-state-machine:
+
+One Way to Implement a Transaction State Machine
+================================================
+
+**Transaction state machines** (**TSMs**) in the Protocol plugin must do
+the following:
+
+-  Keep track of the state of the transaction
+
+-  Handle events received (based on the state of the transaction and the
+   event received)
+
+-  Update the state of the transaction as it changes
+
+Below is one way you can implement TSMs. Details about how the Protocol
+plugin does this are provided in the next section.
+
+-  Create a data structure for transactions that contains all of the
+   state data you need to keep track of. In the Protocol plugin this is
+   a struct, ``Txn_SM``.
+
+-  When you create the TSM's continuation, initialize data of type
+   ``Txn_SM``. Initialize the data to the initial state of a transaction
+   (in this case, a net connection has just been accepted). Associate
+   this data to the TSM continuation using ``TSContDataSet``.
+
+-  Write state handler functions that handle the expected events for
+   each state.
+
+-  Write the handler for the TSM. Its job is to receive events, examine
+   the current state, and execute the appropriate state handler
+   function. In the Protocol plugin, the handler is ``main_handler``.
+   ``main_handler`` calls the state handler functions to handle each
+   state.
+
+The steps below describe the flow of execution illustrated in :ref:`"How
+Transaction State Machines are Implemented in the Protocol
+Plugin" <ImplementTransStMachine>`.
+
+1. The handler for the TSM, (called ``main_handler`` in the Protocol
+   plugin) receives events from the TSM.
+
+2. ``main_handler`` examines the state of the transaction-in
+   particular, it examines the current handler.
+
+3. ``main_handler`` calls the ``current_handler`` (which is one
+   of the state handler functions), and then passes the current event to
+   ``current_handler``. In :ref:`the image
+   below <ImplementTransStMachine>` below, the current handler is
+   called ``state2_handler``.
+
+4. The ``current_handler`` handles the event and updates the data.
+   In :ref:`the image below <ImplementTransStMachine>` below, the state is
+   changed from ``state2`` to ``state3`` (and the current
+   handler is changed from ``state2_handler`` to
+   ``state3_handler``). The next time ``main_handler`` receives
+   an event, it will be processed by ``state3_handler``.
+
+5. ``state2_handler`` arranges the next callback of the TSM.
+   Typically, it gives Traffic Server additional work to do (such as
+   writing a file to cache) so that it can progress to the next state.
+   The TSM (``main_handler``) then waits for the next event to
+   arrive from Traffic Server.
+
+**How Transaction State Machines are Implemented in the Protocol
+Plugin**
+
+.. _ImplementTransStMachine:
+
+.. figure:: ../static/images/sdk/txn_sm.jpg
+   :alt: How Transaction State Machines are Implemented in the Protocol Plugin
+
+   How Transaction State Machines are Implemented in the Protocol Plugin
+
+Processing a Typical Transaction
+================================
+
+The code is contained in the following files:
+
+-  ``Protocol.c`` and ``Protocol.h``
+
+-  ``Accept.c`` and ``Accept.h``
+
+-  ``TxnSM.c`` and ``TxnSM.h``
+
+Below is a step-by-step walk-through of the code that processes a
+typical transaction.
+
+1.  The ``TSPluginInit`` function is in the ``Protocol.c`` file. It
+    checks the validity of the ``plugin.config`` entries (there must be
+    two: a client accept port and a server port) and runs an
+    initialization routine, ``init``.
+
+2.  The ``init`` function (in ``Protocol.c``) creates the plugin's
+    log file using ``TSTextLogObjectCreate``.
+
+3.  The ``init`` function creates the accept state machine using
+    ``AcceptCreate``. The code for ``AcceptCreate`` is in the
+    ``Accept.c`` file.
+
+4.  The accept state machine, like the transaction state machine, keeps
+    track of its state with a data structure. This data structure,
+    ``Accept``, is defined in the ``Accept.h`` file. State data in
+    ``AcceptCreate`` is associated with the new accept state machine
+    via ``TSContDataSet``.
+
+5.  The ``init`` function arranges the callback of the accept state
+    machine when there is a network connection by using
+    ``TSNetAccept``.
+
+6.  The handler for the accept state machine is ``accept_event`` in
+    the ``Accept.c`` file. When Traffic Server's Net Processor sends
+    ``TS_EVENT_NET_ACCEPT`` to the accept state machine,
+    ``accept_event`` creates a transaction state machine
+    (``txn_sm``) by calling ``TxnSMCreate``. Notice that
+    ``accept_event`` creates a mutex for the transaction state
+    machine, since each transaction state machine has its own mutex.
+
+7.  The ``TxnSMCreate`` function is in the ``TxnSM.c`` file. The
+    first thing it does is initialize the transaction's data, which is
+    of type ``TxnSM`` (as defined in ``TxnSM.h``). Notice that the
+    current handler (``q_current_handler``) is set to
+    ``state_start``.
+
+8.  ``TxnSMCreate`` then creates a transaction state machine using
+    ``TSContCreate``. The handler for the transaction state machine
+    is ``main_handler``, which is in the ``TxnSM.c`` file.
+
+9.  When ``accept_event`` receives ``TS_EVENT_NET_ACCEPT``, it
+    calls the transaction state machine (
+    ``TSContCall (txn_sm, 0, NULL);`` ). The event passed to
+    ``main_handler`` is ``0`` (``TS_EVENT_NONE``).
+
+10. The first thing ``main_handler`` does is examine the current
+    ``txn_sm`` state by calling ``TSContDataGet``. The state is
+    ``state_start``.
+
+11. ``main_handler`` then invokes the handler for
+    ``state_start`` by using the function pointer
+    ``TxnSMHandler`` (as defined in ``TxnSM.h``).
+
+12. The ``state_start`` handler function (in the ``TxnSM.c`` file)
+    is handed an event (at this stage, the event is
+    ``TS_EVENT_NET_ACCEPT``) and a client vconnection.
+    ``state_start`` checks to see if this client vconnection is
+    closed; if it is not, then ``state_start`` attempts to read data
+    from the client vconnection into an ``TSIOBuffer``
+    (``state_start`` is handling the event it receives).
+
+13. ``state_start`` changes the current handler to
+    ``state_interface_with_client`` (that is, it updates the state
+    of the transaction to the next state).
+
+14. ``state_start`` initiates a read of the client vconnection
+    (arranges for Traffic Server to send
+    ``TS_EVENT_VCONN_READ_READY`` events to the TSM) by calling
+    ``TSVConnRead``.
+
+15. ``state_interface_with_client`` is activated by the next event
+    from Traffic Server. It checks for errors and examines the read VIO
+    for the read operation initiated by ``TSVConnRead``.
+
+16. If the read VIO is the ``client_read_VIO`` (which we are
+    expecting at this stage in the transaction), then
+    ``state_interface_with_client`` updates the state to
+    ``state_read_request_from_client`` .
+
+17. ``state_read_request_from_client`` handles actual
+    ``TS_EVENT_READ_READY`` events and reads the client request.
+
+18. ``state_read_request_from_client`` parses the client request.
+
+19. ``state_read_request_from_client`` updates the current state to
+    the next state, ``state_handle_cache_lookup`` .
+
+20. ``state_read_request_from_client`` arranges for Traffic Server
+    to call back the TSM with the next set of events (initiating the
+    cache lookup) by calling ``TSCacheRead``.
+
+21. When the ``TSCacheRead`` sends the TSM either
+    ``TS_EVENT_OPEN_READ`` (a cache hit) or
+    ``TS_EVENT_OPEN_READ_FAILED`` (a cache miss),
+    ``main_handler`` calls ``state_handle_cache_lookup``.

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/plugin-interfaces.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/plugin-interfaces.en.rst b/doc/developer-guide/plugins/plugin-interfaces.en.rst
new file mode 100644
index 0000000..53c873b
--- /dev/null
+++ b/doc/developer-guide/plugins/plugin-interfaces.en.rst
@@ -0,0 +1,142 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../../common.defs
+
+.. _developer-plugins-interfaces:
+
+Plugin Interfaces
+*****************
+
+Most of the functions in the Traffic Server API provide an interface to
+specific code modules within Traffic Server. The miscellaneous functions
+described in this chapter provide some useful general capabilities. They
+are categorized as follows:
+
+.. toctree::
+   :maxdepth: 2
+
+The C library already provides functions such as ``printf``, ``malloc``,
+and ``fopen`` to perform these tasks. The Traffic Server API versions,
+however, overcome various C library limitations (such as portability to
+all Traffic Server-support platforms).
+
+.. _developer-plugins-tsfopen-family:
+
+TSfopen Family
+==============
+
+The ``fopen`` family of functions in C is normally used for reading
+configuration files, since ``fgets`` is an easy way to parse files on a
+line-by-line basis. The ``TSfopen`` family of functions aims at solving
+the same problem of buffered IO and line at a time IO in a
+platform-independent manner. The ``fopen`` family of C library functions
+can only open a file if a file descriptor less than 256 is available.
+Since Traffic Server often has more than 2000 file descriptors open at
+once, however, the likelihood of an available file descriptor less than
+256 very small. To solve this problem, the ``TSfopen`` family can open
+files with descriptors greater than 256.
+
+The ``TSfopen`` family of routines is not intended for high speed IO or
+flexibility - they are blocking APIs (not asynchronous). For performance
+reasons, you should not directly use these APIs on a Traffic Server
+thread (when being called back on an HTTP hook); it is better to use a
+separate thread for doing the blocking IO. The ``TSfopen`` family is
+intended for reading and writing configuration information when
+corresponding usage of the ``fopen`` family of functions is
+inappropriate due to file descriptor and portability limitations. The
+``TSfopen`` family of functions consists of the following:
+
+-  :c:func:`TSfclose`
+
+-  :c:func:`TSfflush`
+
+-  :c:func:`TSfgets`
+
+-  :c:func:`TSfopen`
+
+-  :c:func:`TSfread`
+
+-  :c:func:`TSfwrite`
+
+Memory Allocation
+=================
+
+
+Traffic Server provides five routines for allocating and freeing memory.
+These routines correspond to similar routines in the C library. For
+example, ``TSrealloc`` behaves like the C library routine ``realloc``.
+
+There are two main reasons for using the routines provided by Traffic
+Server. The first is portability: the Traffic Server API routines behave
+the same on all of Traffic Server's supported platforms. For example,
+``realloc`` does not accept an argument of ``NULL`` on some platforms.
+The second reason is that the Traffic Server routines actually track the
+memory allocations by file and line number. This tracking is very
+efficient, always turned on, and quite useful when tracking down memory
+leaks.
+
+The memory allocation functions are:
+
+-  :c:func:`TSfree`
+
+-  :c:func:`TSmalloc`
+
+-  :c:func:`TSrealloc`
+
+-  :c:func:`TSstrdup`
+
+-  :c:func:`TSstrndup`
+
+Thread Functions
+================
+
+The Traffic Server API thread functions enable you to create, destroy,
+and identify threads within Traffic Server. Multithreading enables a
+single program to have more than one stream of execution and to process
+more than one transaction at a time. Threads serialize their access to
+shared resources and data using the ``TSMutex`` type, as described in
+:ref:`developer-plugins-mutexes`.
+
+The thread functions are listed below:
+
+-  :c:func:`TSThreadCreate`
+-  :c:func:`TSThreadDestroy`
+-  :c:func:`TSThreadInit`
+-  :c:func:`TSThreadSelf`
+
+Debugging Functions
+===================
+
+-  :c:func:`TSDebug`
+   prints out a formatted statement if you are running Traffic Server in
+   debug mode.
+
+-  :c:func:`TSIsDebugTagSet`
+   checks to see if a debug tag is set. If the debug tag is set, then
+   Traffic Server prints out all debug statements associated with the
+   tag.
+
+-  :c:func:`TSError`
+   prints error messages to Traffic Server's error log
+
+-  :c:func:`TSAssert`
+   enables the use of assertion in a plugin.
+
+-  :c:func:`TSReleaseAssert`
+   enables the use of assertion in a plugin.
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/plugin-management/index.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/plugin-management/index.en.rst b/doc/developer-guide/plugins/plugin-management/index.en.rst
new file mode 100644
index 0000000..6dec702
--- /dev/null
+++ b/doc/developer-guide/plugins/plugin-management/index.en.rst
@@ -0,0 +1,32 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../../../common.defs
+
+.. _developer-plugins-management:
+
+Plugin Management
+*****************
+
+This chapter covers the following topics:
+
+.. toctree::
+   :maxdepth: 2
+
+   settings-and-statistics.en
+   logging-api.en
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/plugin-management/logging-api.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/plugin-management/logging-api.en.rst b/doc/developer-guide/plugins/plugin-management/logging-api.en.rst
new file mode 100644
index 0000000..36d73ab
--- /dev/null
+++ b/doc/developer-guide/plugins/plugin-management/logging-api.en.rst
@@ -0,0 +1,120 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../../../common.defs
+
+.. _developer-plugins-management-logging-api:
+
+Logging API
+***********
+
+The logging API enables your plugin to log entries in a custom text log
+file that you create with the call :c:func:`TSTextLogObjectCreate`. This log
+file is part of Traffic Server's logging system; by default, it is
+stored in the logging directory. Once you have created the log object,
+you can set log properties.
+
+The logging API enables you to:
+
+-  Establish a custom text log for your plugin: see
+   :c:func:`TSTextLogObjectCreate`
+
+-  Set the log header for your custom text log: see
+   :c:func:`TSTextLogObjectHeaderSet`
+
+-  Enable or disable rolling your custom text log: see
+   :c:func:`TSTextLogObjectRollingEnabledSet`
+
+-  Set the rolling interval (in seconds) for your custom text log: see
+   :c:func:`TSTextLogObjectRollingIntervalSecSet`
+
+-  Set the rolling offset for your custom text log: see
+   :c:func:`TSTextLogObjectRollingOffsetHrSet`
+
+-  Set the rolling size for your custom text log: see
+   :c:func:`TSTextLogObjectRollingSizeMbSet`
+
+-  Write text entries to the custom text log: see
+   :c:func:`TSTextLogObjectWrite`
+
+-  Flush the contents of the custom text log's write buffer to disk: see
+   :c:func:`TSTextLogObjectFlush`
+
+-  Destroy custom text logs when you are done with them: see
+   :c:func:`TSTextLogObjectDestroy`
+
+The steps below show how the logging API is used in the
+``blacklist-1.c`` sample plugin. For the complete source code, see the
+:ref:`developer-plugins-examples-blacklist-code` section.
+
+#. A new log file is defined as a global variable.
+
+   .. code-block:: c
+
+         static TSTextLogObject log;
+
+#. In ``TSPluginInit``, a new log object is allocated:
+
+   .. code-block:: c
+
+           TSReturnCode error = TSTextLogObjectCreate("blacklist",
+                                TS_LOG_MODE_ADD_TIMESTAMP, &log);
+
+   The new log is named ``blacklist.log``. Each entry written to the log
+   will have a timestamp. The ``NULL`` argument specifies that the new
+   log does not have a log header. The error argument stores the result
+   of the log creation; if the log is created successfully, then an
+   error will be equal to ``TS_LOG_ERROR_NO_ERROR``.
+
+#. After creating the log, the plugin makes sure that the log was
+   created successfully:
+
+   .. code-block:: c
+
+       if (error != TS_SUCCESS) {
+           printf("Blacklist plugin: error %d while creating log\n", error);
+       }
+
+#. The :ref:`developer-plugins-examples-blacklist` matches the host portion of
+   the URL (in each client request) with a list of blacklisted sites (stored in
+   the array ``sites[]``):
+
+   .. code-block:: c
+
+       for (i = 0; i < nsites; i++) { if (strncmp (host, sites[i],
+       host\_length) == 0) {
+
+   If the host matches one of the blacklisted
+   sites (such as ``sites[i]``), then the plugin writes a blacklist
+   entry to ``blacklist.log``:
+
+   .. code-block:: c
+
+       if (log) { TSTextLogObjectWrite(log, "blacklisting site: %s",
+       sites[i]);
+
+   The format of the log entry is as follows:
+
+   ::
+
+       blacklisting site: sites[i]
+
+   The log is not flushed or
+   destroyed in the ``blacklist-1`` plugin - it lives for the life of
+   the plugin.
+
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/plugins/plugin-management/settings-and-statistics.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/plugins/plugin-management/settings-and-statistics.en.rst b/doc/developer-guide/plugins/plugin-management/settings-and-statistics.en.rst
new file mode 100644
index 0000000..1cd4bcf
--- /dev/null
+++ b/doc/developer-guide/plugins/plugin-management/settings-and-statistics.en.rst
@@ -0,0 +1,59 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../../../common.defs
+
+.. _developer-plugins-management-settings-and-statistics:
+
+Settings and Statistics
+***********************
+
+Your plugin might need to know information about Traffic Server's
+current configuration and performance. The functions described in this
+section read this information from the Traffic Server :file:`records.config`
+file. Configuration settings are stored in ``CONFIG`` variables and
+statistics are stored in ``PROCESS`` variables.
+
+.. caution::
+
+   Not all ``CONFIG`` and ``PROCESS`` variables in :file:`records.config` are
+   relevant to Traffic Server's configuration and statistics. Therefore,
+   retrieve only the :file:`records.config` variables that are documented in
+   the :ref:`admin-guide`.
+
+To retrieve a variable, you need to know its type (``int``, ``counter``,
+``float``, or ``string``). Plugins store the :file:`records.config` values
+as an ``TSMgmtInt``, ``TSMgmtCounter``, ``TSMgmtFloat``, or
+``TSMgmtString``. You can look up :file:`records.config` variable types in
+the :ref:`admin-guide`.
+
+Depending on the result type, you'll use ``TSMgmtIntGet``,
+``TSMgmtCounterGet``, ``TSMgmtFloatGet``, or ``TSMgmtStringGet`` to
+obtain the variable value (see the example for
+:c:func:`TSMgmtIntGet`.
+
+The ``TSMgmt*Get`` functions are:
+
+-  :c:func:`TSMgmtCounterGet`
+
+-  :c:func:`TSMgmtFloatGet`
+
+-  :c:func:`TSMgmtIntGet`
+
+-  :c:func:`TSMgmtStringGet`
+
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/release-process/index.en.rst
----------------------------------------------------------------------
diff --git a/doc/developer-guide/release-process/index.en.rst b/doc/developer-guide/release-process/index.en.rst
new file mode 100644
index 0000000..e056ff1
--- /dev/null
+++ b/doc/developer-guide/release-process/index.en.rst
@@ -0,0 +1,174 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing,
+   software distributed under the License is distributed on an
+   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+   KIND, either express or implied.  See the License for the
+   specific language governing permissions and limitations
+   under the License.
+
+.. include:: ../../common.defs
+
+.. _developer-release-process:
+
+Release Process
+***************
+
+Managing a release is easiest in an environment that is as clean as possible.
+For this reason, cloning the code base in to a new directory for the release
+process is recommended.
+
+Requirements
+============
+
+* A system for git and building.
+
+* A cryptographic key that has been signed by at least two other PMC members.
+  This should be preferentially associated with your ``apache.org`` email
+  address but that is not required.
+
+.. _release-management-release-candidate:
+
+Release Candidate
+=================
+
+The first step in a release is making a release candidate. This is distributed
+to the community for validation before the actual release.
+
+Document
+========
+
+Gather up information about the changes for the release. The ``CHANGES`` file
+is a good starting point. You may also want to check the commits since the last
+release. The primary purpose of this is to generate a list of the important
+changes since the last release.
+
+Create or update a page on the Wiki for the release. If it is a major or minor
+release it should have its own page. Use the previous release page as a
+template. Point releases should get a section at the end of the corresponding
+release page.
+
+Write an announcement for the release. This will contain much of the same
+information that is on the Wiki page but more concisely. Check the
+`mailing list archives <http://mail-archives.apache.org/mod_mbox/trafficserver-dev/>`_
+for examples to use as a base.
+
+Build
+=====
+
+#. Go to the top level source directory.
+
+#. Check the version in ``configure.ac``. There are two values near the top that
+   need to be set, ``TS_VERSION_S`` and ``TS_VERSION_N``. These are the release
+   version number in different encodings.
+
+#. Check the variable ``RC`` in the top level ``Makefile.am``. This should be
+   the point release value. This needs to be changed for every release
+   candidate. The first release candidate is ``0`` (zero).
+
+#. Execute the following commands to make the distribution files. ::
+
+      autoreconf -i
+      ./configure
+      make rel-candidate
+
+These steps will create the distribution files and sign them using your key.
+Expect to be prompted twice for your passphrase unless you use an ssh key agent.
+If you have multiple keys you will need to set the default appropriately
+beforehand, as no option will be provided to select the signing key. The files
+should have names that start with ``trafficserver-X.Y.Z-rcA.tar.bz2`` where
+``X.Y.Z`` is the version and ``A`` is the release candidate counter. There
+should be four such files, one with no extension and three others with the
+extensions ``asc``, ``md5``, and ``sha1``. This will also create a signed git
+tag of the form ``X.Y.Z-rcA``.
+
+Distribute
+==========
+
+The release candidate files should be uploaded to some public storage. Your
+personal storage on *people.apach.org* is a reasonable location to use.
+
+Send the release candiate announcement to the *users* and *dev* mailinging
+lists, noting that it is a release *candidate* and providing a link to the
+distribution files you uploaded. This announcement should also call for a vote
+on the candidate, generally with a 72 hours time limit.
+
+If the voting was successful (at least three "+1" votes and no "-1" votes),
+proceed to :ref:`release-management-official-release`. Otherwise, repeat the
+:ref:`release-management-release-candidate` process.
+
+.. _release-management-official-release:
+
+Official Release
+================
+
+Build the distribution files with the command ::
+
+   make release
+
+Be sure to not have changed anything since the release candidate was built so
+the checksums are identical. This will create a signed git tag of the form
+``X.Y.Z`` and produce the distribution files. Push the tag to the ASF repository
+with the command ::
+
+   git push origin X.Y.Z
+
+This presumes ``origin`` is the name for the ASF remote repository which is
+correct if you originally clone from the ASF repository.
+
+The distribution files must be added to an SVN repository. This can be accessed
+with the command::
+
+   svn co https://dist.apache.org/repos/dist/release/trafficserver <local-directory>
+
+All four of the distribution files go here. If you are making a point release
+then you should also remove the distribution files for the previous release.
+Allow 24 hours for the files to be distributed through the ASF infrastructure.
+
+The Traffic Server website must be updated. This is an SVN repository which you
+can access with ::
+
+   svn co https://svn.apache.org/repos/asf/trafficserver/site/trunk <local-directory>
+
+The files of interest are in the ``content`` directory.
+
+``index.html``
+   This is the front page. The places to edit here are any security
+   announcements at the top and the "News" section.
+
+``downloads.en.mdtext``
+   Update the downloads page to point to the new download objects.
+
+After making changes, commit them and then run ::
+
+   publish.pl trafficserver <apache-id>
+
+On the ``people.apache.org`` host.
+
+If needed, update the Wiki page for the release to point at the release
+distribution files.
+
+Update the announcement, if needed, to refer to the release distribution files
+and remove the comments concerning the release candidate. This announcement
+should be sent to the *users* and *dev* mailing lists. It should also be sent
+to the ASF announcement list, which must be done using an ``apache.org`` email
+address.
+
+Finally, update various files after the release:
+
+* The ``STATUS`` file for master and for the release branch to include this version.
+
+* The ``CHANGES`` file to have a header for the next version.
+
+* ``configure.ac`` to be set to the next version.
+
+* In the top level ``Makefile.am`` change ``RC`` to have the value ``0``.
+

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/ce162a6d/doc/developer-guide/skeleton
----------------------------------------------------------------------
diff --git a/doc/developer-guide/skeleton b/doc/developer-guide/skeleton
new file mode 100755
index 0000000..0e56f80
--- /dev/null
+++ b/doc/developer-guide/skeleton
@@ -0,0 +1,134 @@
+#! /usr/bin/env perl
+
+#  Licensed to the Apache Software Foundation (ASF) under one 
+#  or more contributor license agreements.  See the NOTICE file 
+#  distributed with this work for additional information 
+#  regarding copyright ownership.  The ASF licenses this file 
+#  to you under the Apache License, Version 2.0 (the 
+#  "License"); you may not use this file except in compliance 
+#  with the License.  You may obtain a copy of the License at 
+# 
+#      http://www.apache.org/licenses/LICENSE-2.0 
+# 
+#  Unless required by applicable law or agreed to in writing, software 
+#  distributed under the License is distributed on an "AS IS" BASIS, 
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+#  See the License for the specific language governing permissions and 
+
+# usage: skeleton [--header=PATH ...] API ...
+# Using declarations from the given headers, generate a skeleton man page
+# for the named APIs.
+
+use 5.012;
+use warnings;
+use autodie;
+use Getopt::Long;
+
+sub slurp
+{
+  my $path = shift;
+  open(my $fh, "<", $path);
+  return do { local $/; <$fh> }
+}
+
+sub datestamp
+{
+  use POSIX qw/strftime/;
+
+  return strftime "%B %d, %Y", localtime;
+}
+
+# Extract the function declarations from an ATS header file.
+sub parse
+{
+  my $decls = [];
+
+  foreach my $header (@_) {
+    my $defs = slurp($header);
+
+    while ($defs =~ m/
+        tsapi\s+        # Start with 'tsapi'
+        ([^;\(]+)       # Capture the followinf return value
+        \s+(\w+)\s*     # Capture the word before the opening parenthesis
+        \(([^\)]+)\)    # Capture the arguments
+        .*\;/xg) {
+      chomp $1; chomp $2; chomp $3;
+      my $d ={ return => $1, name => $2, args => $3 };
+      $d->{args} =~ s/\n//g;
+      push @$decls, $d;
+    }
+  }
+
+  return $decls;
+}
+
+# Return a mandoc declaration for the given API name.
+sub define
+{
+  my $decls = shift;
+  my $name = shift;
+
+  foreach my $d (@$decls) {
+    if ($d->{name} eq $name) {
+      my @args;
+      my $mdoc;
+      @args = split(/,\s+/, $d->{args}); # split args at comma boundaries
+      @args = map { "\"$_\"" } @args; # quote each arg list element
+      $mdoc =
+          ".Ft \"" . $d->{return} . "\"\n" .
+          ".Fo " . $name . "\n" .
+          ".Fa " . join("\n.Fa ", @args) . "\n" .
+          ".Fc";
+      $mdoc =~ s/^\s+(.*)\s+$/$1/;
+      return $mdoc;
+    }
+  }
+}
+
+my @headers = ();
+my $options = GetOptions(
+  "header=s" => \@headers
+);
+
+my $decls = parse(@headers);
+#say define($decls, @ARGV);
+
+print <<EOF;
+.\\"  Licensed to the Apache Software Foundation (ASF) under one .\\"
+.\\"  or more contributor license agreements.  See the NOTICE file .\\"
+.\\"  distributed with this work for additional information .\\"
+.\\"  regarding copyright ownership.  The ASF licenses this file .\\"
+.\\"  to you under the Apache License, Version 2.0 (the .\\"
+.\\"  "License"); you may not use this file except in compliance .\\"
+.\\"  with the License.  You may obtain a copy of the License at .\\"
+.\\" .\\"
+.\\"      http://www.apache.org/licenses/LICENSE-2.0 .\\"
+.\\" .\\"
+.\\"  Unless required by applicable law or agreed to in writing, software .\\"
+.\\"  distributed under the License is distributed on an "AS IS" BASIS, .\\"
+.\\"  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. .\\"
+.\\"  See the License for the specific language governing permissions and .\\"
+.Dd @{[ datestamp() ]}
+.Dt @{[ $ARGV[0] ]} 3ts TSAPI
+.Sh NAME
+.Nm @{[ join(",\n.Nm ", @ARGV) ]}
+.Nd XXX Api short description
+.Sh LIBRARY
+Apache Traffic Server plugin API
+.Sh SYNOPSIS
+.In ts/ts.h
+EOF
+
+print @{[ map { define($decls, $_) . "\n" } @ARGV ]};
+
+print <<EOF;
+.Sh DESCRIPTION
+.Sh RETURN VALUES
+.Sh EXAMPLES
+.nf
+#include <ts/ts.h>
+.fi
+.Sh SEE ALSO
+.Xr TSAPI 3ts
+EOF
+# vim: set ts=2 sw=2 et :