summaryrefslogtreecommitdiffstats
path: root/docs/nspr/nspr_poll_method.rst
diff options
context:
space:
mode:
Diffstat (limited to 'docs/nspr/nspr_poll_method.rst')
-rw-r--r--docs/nspr/nspr_poll_method.rst134
1 files changed, 134 insertions, 0 deletions
diff --git a/docs/nspr/nspr_poll_method.rst b/docs/nspr/nspr_poll_method.rst
new file mode 100644
index 0000000000..6c15861562
--- /dev/null
+++ b/docs/nspr/nspr_poll_method.rst
@@ -0,0 +1,134 @@
+NSPR pool method
+================
+
+This technical note documents the poll method of PRFileDesc. The poll
+method is not to be confused with the PR_Poll function. The poll method
+operates on a single NetScape Portable Runtime (NSPR) file descriptor,
+whereas PR_Poll operates on a collection of NSPR file descriptors.
+PR_Poll uses the poll method behind the scene, but it is also possible
+to use the poll method directly.
+
+We consider a stack of *NSPR I/O layers* on top of the *network
+transport*. Each I/O layer is represented by a PRFileDesc structure and
+the protocol of that layer is implemented by a PRIOMethods table. The
+bottom layer is a wrapper for the underlying network transport. The NSPR
+library provides a reference implementation of the bottom layer using
+the sockets API, but you can provide your own implementation of the
+bottom layer using another network transport API. The poll method is one
+of the functions in the PRIOMethods table. The prototype of the poll
+method is
+
+.. code::
+
+ PRInt16 poll_method(PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags);
+
+The purpose of the poll method is to allow a layer to modify that flags
+that will ultimately be used in the call to the underlying network
+transport's select (or equivalent) function, and to indicate that a
+layer is already able to make progress in the manner suggested by the
+polling flags. The arguments and return value of the poll method are
+described below.
+
+.. _in_flags_input_argument:
+
+in_flags [input argument]
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The in_flags argument specifies the events at the **top layer** of the
+I/O layer stack that the caller is interested in.
+
+- For PR_Recv, you should pass PR_POLL_READ as the in_flags argument to
+ the poll method
+- For PR_Send, you should pass PR_POLL_WRITE as the in_flags argument
+ to the poll method
+
+.. _out_flags_output_argument:
+
+out_flags [output argument]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If an I/O layer is ready to satisfy the I/O request defined by in_flags
+without involving the underlying network transport, its poll method sets
+the corresponding event in \*out_flags on return.
+
+For example, consider an I/O layer that buffers input data. If the
+caller wishes to test for read ready (that is, PR_POLL_READ is set in
+in_flags) and the layer has input data buffered, the poll method would
+set the PR_POLL_READ event in \*out_flags. It can determine that without
+asking the underlying network transport.
+
+The current implementation of PR_Poll (the primary user of the poll
+method) requires that the events in \*out_flags reflect the caller's
+view. This requirement may be relaxed in a future NSPR release. To
+remain compatible with this potential semantic change, NSPR clients
+should only use \*out_flags as described in the *How to use the poll
+method* section below.
+
+.. _Return_value:
+
+Return value
+~~~~~~~~~~~~
+
+If the poll method stores a nonzero value in \*out_flags, the return
+value will be the value of in_flags. (Note: this may change in a future
+NSPR release if we make the semantic change to \*out_flags mentioned
+above. Therefore, NSPR clients should only use the return value as
+described in *How to use the poll method* section below.) If the poll
+method stores zero in \*out_flags, the return value will be the bottom
+layer's desires with respect to the in_flags. Those are the events that
+the caller should poll the underlying network transport for. These
+events may be different from the events in in_flags (which reflect the
+caller's view) for some protocols.
+
+.. _How_to_use_the_poll_method:
+
+How to use the poll method
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The poll method should only be used with a NSPR file descriptor in
+**non-blocking** mode. Most NSPR clients call PR_Poll and do not call
+the poll method directly. However, PR_Poll can only used with a stack
+whose bottom layer is NSPR's reference implementation. If you are using
+your own implementation of the bottom layer, you must call the poll
+method as follows.
+
+Declare two PRInt16 variables to receive the return value and the
+out_flags output argument of the poll method.
+
+.. code::
+
+ PRInt16 new_flags, out_flags;
+
+If you are going to call PR_Recv, pass PR_POLL_READ as the in_flags
+argument.
+
+.. code::
+
+ new_flags = fd->methods->poll(fd, PR_POLL_READ, &out_flags);
+
+If you are going to call PR_Send, pass PR_POLL_WRITE as the in_flags
+argument.
+
+.. code::
+
+ new_flags = fd->methods->poll(fd, PR_POLL_WRITE, &out_flags);
+
+If you are interested in calling both PR_Recv and PR_Send on the same
+file descriptor, make two separate calls to the poll method, one with
+PR_POLL_READ as in_flags and the other with PR_POLL_WRITE as in_flags,
+so that you know what events at the network transport layer PR_POLL_READ
+and PR_POLL_WRITE are mapped to, respectively.
+
+On return, if (new_flags & out_flags) is nonzero, you can try PR_Recv or
+PR_Send immediately.
+
+Otherwise ((new_flags & out_flags) is 0), you should do the following.
+
+- If new_flags contains PR_POLL_READ, you should try PR_Recv or PR_Send
+ when the underlying network transport is readable
+- If new_flags contains PR_POLL_WRITE, you should try PR_Recv or
+ PR_Send when the underlying network transport is writable
+
+**Important** do not use out_flags in any way other than testing if
+(new_flags & out_flags) is 0. This is how PR_Poll (the primary user and
+hence the de facto specification of the poll method) uses out_flags.