Bug 1858921 - Part 2: Move WasmStructObject inlinable allocation methods to new inlin...
[gecko.git] / docs / nspr / nonblocking_io_in_nspr.rst
bloba5ba816412a2ba09b5904ac4adfc05cf80721490
1 Nonblocking IO in NSPR
2 ======================
5 Introduction
6 ------------
8 Previously, all I/O in the NetScape Portable Runtime (NSPR) was
9 *blocking* (or *synchronous*). A thread invoking an io function is
10 blocked until the io operation is finished. The blocking io model
11 encourages the use of multiple threads as a programming model. A thread
12 is typically created to attend to one of the simultaneous I/O operations
13 that may potentially block.
15 In the *nonblocking* io model, a file descriptor may be marked as
16 nonblocking. An io function on a nonblocking file descriptor either
17 succeeds immediately or fails immediately with
18 <tt>PR_WOULD_BLOCK_ERROR</tt>. A single thread is sufficient to attend
19 to multiple nonblocking file descriptors simultaneously. Typically, this
20 central thread invokes <tt>PR_Poll()</tt> on a set of nonblocking file
21 descriptors. (Note: <tt>PR_Poll()</tt> also works with blocking file
22 descriptors, although it is less useful in the blocking io model.) When
23 <tt>PR_Poll()</tt> reports that a file descriptor is ready for some io
24 operation, the central thread invokes that io function on the file
25 descriptor.
27 .. _Creating_a_Nonblocking_Socket:
29 Creating a Nonblocking Socket
30 -----------------------------
32 *Only sockets can be made nonblocking*. Regular files always operate in
33 blocking mode. This is not a serious constraint as one can assume that
34 disk I/O never blocks. Fundamentally, this constraint is due to the fact
35 that nonblocking I/O and <tt>select()</tt> are only available to sockets
36 on some platforms (e.g., Winsock).
38 In NSPR, a new socket returned by <tt>PR_NewTCPSocket()</tt> or
39 <tt>PR_NewUDPSocket()</tt> is always created in blocking mode. One can
40 make the new socket nonblocking by using <tt>PR_SetSockOpt()</tt> as in
41 the example below (error checking is omitted for clarity):
44 | <tt>PRFileDesc \*sock;</tt>
45 | **<tt>PRIntn optval = 1;</tt>**
47 <tt>sock = PR_NewTCPSocket();</tt>
51    /*
52    * Make the socket nonblocking
53    */
55    PR_SetSockOpt(sock, PR_SockOpt_Nonblocking, &optval, sizeof(optval));
57 .. _Programming_Constraints:
59 Programming Constraints
60 -----------------------
62 There are some constraints due to the use of NT asynchronous I/O in the
63 NSPR. In NSPR, blocking sockets on NT are associated with an I/O
64 completion port. Once associated with an I/O completion port, we can't
65 disassociate the socket from the I/O completion port. I have seen some
66 strange problems with using a nonblocking socket associated with an I/O
67 completion port. So the first constraint is:
69    **The blocking/nonblocking io mode of a new socket is committed the
70    first time a potentially-blocking io function is invoked on the
71    socket. Once the io mode of a socket is committed, it cannot be
72    changed.**
74 The potentially-blocking io functions include <tt>PR_Connect()</tt>,
75 <tt>PR_Accept()</tt>, <tt>PR_AcceptRead()</tt>, <tt>PR_Read()</tt>,
76 <tt>PR_Write()</tt>, <tt>PR_Writev()</tt>, <tt>PR_Recv()</tt>,
77 <tt>PR_Send()</tt>, <tt>PR_RecvFrom()</tt>, <tt>PR_SendTo()</tt>, and
78 <tt>PR_TransmitFile(),</tt> and do not include <tt>PR_Bind()</tt> and
79 <tt>PR_Listen()</tt>.
81 In blocking mode, any of these potentially-blocking functions requires
82 the use of the NT I/O completion port. So at that point we must
83 determine whether to associate the socket with the I/O completion or
84 not, and that decision cannot be changed later.
86 There is a second constraint, due to the use of NT asynchronous I/O and
87 the recycling of used sockets:
89    **The new socket returned by <tt>PR_Accept()</tt> or
90    <tt>PR_AcceptRead()</tt> inherits the blocking/nonblocking io mode of
91    the listening socket and this cannot be changed.**
93 The socket returned by <tt>PR_Accept()</tt> or <tt>PR_AcceptRead()</tt>
94 on a blocking, listening socket may be a recycled socket previously used
95 in a <tt>PR_TransmitFile()</tt> call. Since <tt>PR_TransmitFile()</tt>
96 only operates in blocking mode, this recycled socket can only be reused
97 in blocking mode, hence the above constraint.
99 Because these constraints only apply to NT, it is advised that you test
100 your cross-platform code that uses nonblocking io on NT early in the
101 development cycle. These constraints are enforced in the debug NSPR
102 library by assertions.
104 .. _Differences_from_Blocking_IO:
106 Differences from Blocking IO
107 ----------------------------
109 -  In nonblocking mode, the timeout argument for the io functions is
110    ignored.
111 -  <tt>PR_AcceptRead()</tt> and <tt>PR_TransmitFile()</tt> only work on
112    blocking sockets. They do not make sense in nonblocking mode.
113 -  <tt>PR_Write()</tt>, <tt>PR_Send()</tt>, <tt>PR_Writev()</tt> in
114    blocking mode block until the entire buffer is sent. In nonblocking
115    mode, they cannot block, so they may return with just sending part of
116    the buffer.
118 .. _PR_Poll()_or_PR_Select():
120 PR_Poll() or PR_Select()?
121 -------------------------
123 <tt>PR_Select()</tt> is deprecated, now declared in
124 <tt>private/pprio.h</tt>. Use <tt>PR_Poll()</tt> instead.
126 The current implementation of <tt>PR_Select()</tt> simply calls
127 <tt>PR_Poll()</tt>, so it is sure to have worse performance. Also,
128 native file descriptors (socket handles) cannot be added to
129 <tt>PR_fd_set</tt>, i.e., the functions <tt>PR_FD_NSET</tt>,
130 <tt>PR_FD_NCLR</tt>, <tt>PR_FD_NISSET</tt> do not work.
132 PR_Available()
133 --------------
135 When <tt>PR_Available()</tt> returns 0, it may mean one of two things:
137 -  There is no data available for reading on that socket. I.e.,
138    <tt>PR_Recv()</tt> would block (a blocking socket) or fail with
139    <tt>PR_WOULD_BLOCK_ERROR</tt> (a nonblocking socket).
140 -  The TCP connection on that socket has been closed (end of stream).
142 These two cases can be distinguished by <tt>PR_Poll()</tt>. If
143 <tt>PR_Poll()</tt> reports that the socket is readable (i.e.,
144 <tt>PR_POLL_READ</tt> is set in <tt>out_flags</tt>), and
145 <tt>PR_Available()</tt> returns 0, this means that the socket connection
146 is closed.
148 .. _Current_Status:
150 Current Status
151 --------------
153 Implemented across all supported platforms.