tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nspr_poll_method.rst (5405B)


      1 NSPR pool method
      2 ================
      3 
      4 This technical note documents the poll method of PRFileDesc. The poll
      5 method is not to be confused with the PR_Poll function. The poll method
      6 operates on a single NetScape Portable Runtime (NSPR) file descriptor,
      7 whereas PR_Poll operates on a collection of NSPR file descriptors.
      8 PR_Poll uses the poll method behind the scene, but it is also possible
      9 to use the poll method directly.
     10 
     11 We consider a stack of *NSPR I/O layers* on top of the *network
     12 transport*. Each I/O layer is represented by a PRFileDesc structure and
     13 the protocol of that layer is implemented by a PRIOMethods table. The
     14 bottom layer is a wrapper for the underlying network transport. The NSPR
     15 library provides a reference implementation of the bottom layer using
     16 the sockets API, but you can provide your own implementation of the
     17 bottom layer using another network transport API. The poll method is one
     18 of the functions in the PRIOMethods table. The prototype of the poll
     19 method is
     20 
     21 .. code::
     22 
     23   PRInt16 poll_method(PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags);
     24 
     25 The purpose of the poll method is to allow a layer to modify that flags
     26 that will ultimately be used in the call to the underlying network
     27 transport's select (or equivalent) function, and to indicate that a
     28 layer is already able to make progress in the manner suggested by the
     29 polling flags. The arguments and return value of the poll method are
     30 described below.
     31 
     32 .. _in_flags_input_argument:
     33 
     34 in_flags [input argument]
     35 ~~~~~~~~~~~~~~~~~~~~~~~~~
     36 
     37 The in_flags argument specifies the events at the **top layer** of the
     38 I/O layer stack that the caller is interested in.
     39 
     40 -  For PR_Recv, you should pass PR_POLL_READ as the in_flags argument to
     41   the poll method
     42 -  For PR_Send, you should pass PR_POLL_WRITE as the in_flags argument
     43   to the poll method
     44 
     45 .. _out_flags_output_argument:
     46 
     47 out_flags [output argument]
     48 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
     49 
     50 If an I/O layer is ready to satisfy the I/O request defined by in_flags
     51 without involving the underlying network transport, its poll method sets
     52 the corresponding event in \*out_flags on return.
     53 
     54 For example, consider an I/O layer that buffers input data. If the
     55 caller wishes to test for read ready (that is, PR_POLL_READ is set in
     56 in_flags) and the layer has input data buffered, the poll method would
     57 set the PR_POLL_READ event in \*out_flags. It can determine that without
     58 asking the underlying network transport.
     59 
     60 The current implementation of PR_Poll (the primary user of the poll
     61 method) requires that the events in \*out_flags reflect the caller's
     62 view. This requirement may be relaxed in a future NSPR release. To
     63 remain compatible with this potential semantic change, NSPR clients
     64 should only use \*out_flags as described in the *How to use the poll
     65 method* section below.
     66 
     67 .. _Return_value:
     68 
     69 Return value
     70 ~~~~~~~~~~~~
     71 
     72 If the poll method stores a nonzero value in \*out_flags, the return
     73 value will be the value of in_flags. (Note: this may change in a future
     74 NSPR release if we make the semantic change to \*out_flags mentioned
     75 above. Therefore, NSPR clients should only use the return value as
     76 described in *How to use the poll method* section below.) If the poll
     77 method stores zero in \*out_flags, the return value will be the bottom
     78 layer's desires with respect to the in_flags. Those are the events that
     79 the caller should poll the underlying network transport for. These
     80 events may be different from the events in in_flags (which reflect the
     81 caller's view) for some protocols.
     82 
     83 .. _How_to_use_the_poll_method:
     84 
     85 How to use the poll method
     86 ~~~~~~~~~~~~~~~~~~~~~~~~~~
     87 
     88 The poll method should only be used with a NSPR file descriptor in
     89 **non-blocking** mode. Most NSPR clients call PR_Poll and do not call
     90 the poll method directly. However, PR_Poll can only used with a stack
     91 whose bottom layer is NSPR's reference implementation. If you are using
     92 your own implementation of the bottom layer, you must call the poll
     93 method as follows.
     94 
     95 Declare two PRInt16 variables to receive the return value and the
     96 out_flags output argument of the poll method.
     97 
     98 .. code::
     99 
    100   PRInt16 new_flags, out_flags;
    101 
    102 If you are going to call PR_Recv, pass PR_POLL_READ as the in_flags
    103 argument.
    104 
    105 .. code::
    106 
    107   new_flags = fd->methods->poll(fd, PR_POLL_READ, &out_flags);
    108 
    109 If you are going to call PR_Send, pass PR_POLL_WRITE as the in_flags
    110 argument.
    111 
    112 .. code::
    113 
    114   new_flags = fd->methods->poll(fd, PR_POLL_WRITE, &out_flags);
    115 
    116 If you are interested in calling both PR_Recv and PR_Send on the same
    117 file descriptor, make two separate calls to the poll method, one with
    118 PR_POLL_READ as in_flags and the other with PR_POLL_WRITE as in_flags,
    119 so that you know what events at the network transport layer PR_POLL_READ
    120 and PR_POLL_WRITE are mapped to, respectively.
    121 
    122 On return, if (new_flags & out_flags) is nonzero, you can try PR_Recv or
    123 PR_Send immediately.
    124 
    125 Otherwise ((new_flags & out_flags) is 0), you should do the following.
    126 
    127 -  If new_flags contains PR_POLL_READ, you should try PR_Recv or PR_Send
    128   when the underlying network transport is readable
    129 -  If new_flags contains PR_POLL_WRITE, you should try PR_Recv or
    130   PR_Send when the underlying network transport is writable
    131 
    132 **Important** do not use out_flags in any way other than testing if
    133 (new_flags & out_flags) is 0. This is how PR_Poll (the primary user and
    134 hence the de facto specification of the poll method) uses out_flags.