]> git.ipfire.org Git - thirdparty/squid.git/blame - src/Comm.dox
Source Format Enforcement (#1234)
[thirdparty/squid.git] / src / Comm.dox
CommitLineData
9a1b46cc 1/*
b8ae064d 2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
9a1b46cc
AJ
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
946b016d
AR
9/**
10\defgroup Comm Comm Module
11\ingroup Components
9603207d 12
946b016d
AR
13
14\section Basic Basic Comm API principles
15
16 \par
17 Comm API supports four major kinds of socket-related operations:
18 accept, connect, read, and write. Sockets are identified by their
19 descriptors.
20
21 \par
22 A Comm user requests its interest in operations by calling an
23 appropriate API function (e.g., comm_read()) and optionally providing
24 a notification "callback" (a.k.a., handler). For a given descriptor,
25 there can be no more than one registered user per operation.
26
27 \par
28 In addition to the four operations listed above, a user can register
29 to be notified when a given descriptor is closed.
30
31 \par
32 When a Comm operation completes, all users that registered the
33 corresponding handler are notified. When a descriptor is closed, all
34 users that registered any callback for the descriptor are notified
35 (this will change though, see "Anticipated changes" below).
36
37 \par
38 All Comm notifications are asynchronous, performed using the
39 AsyncCall API.
40
41 \par
42 Notifications for four operations listed above are scheduled in the
43 order of the corresponding operations completion. User code can assume
44 that the operation has completed (possibly with an error) only after
45 receiving a notification. Until then, I/O resources such as buffers
46 must remain available for the operation.
47
48 \par
49 Notifications related to closing of a descriptor are documented
50 separately.
51
52
53\section IO-cancel I/O cancellation
54
55 \par
56 To cancel an interest in a read operation, call comm_read_cancel()
57 with an AsyncCall object. This call guarantees that the passed Call
58 will be canceled (see the AsyncCall API for call cancellation
59 definitions and details). Naturally, the code has to store the
9603207d 60 original read callback Call pointer to use this interface.
946b016d
AR
61
62 \par
63 The comm_read_cancel() call does not guarantee that the read operation
64 has not already happen.
65
66 \par
67 The comm_read_cancel() call guarantees that the read operation will not
68 start for read operations that are performed by Comm (i.e., where read
69 start is controlled by Comm). There is no such guarantee for
70 asynchronous read operations scheduled by Comm but started by the
71 operating system or other threads.
72
73 \par
74 The above applies to comm_read_cancel() interface with an AsyncCall
75 object as a parameter. You cannot reliably cancel an interest in read
76 operation using the old comm_read_cancel() call that uses a function
77 pointer. The handler may get even called after old comm_read_cancel()
78 was called.
79
80 \par
81 It is OK to call comm_read_cancel (both flavors) at any time as long
82 as the descriptor has not been closed and there is either no read
83 interest registered or the passed parameters match the registered
84 ones. If the descriptor has been closed, the behavior is undefined.
85 Otherwise, if parameters do not match, you get an assertion.
86
87 \par
88 To cancel Comm operations other than read, close the descriptor with
89 comm_close().
90
91
92\section comm-close Descriptor closing with comm_close
93
94 \par
95 The comm_close() function does not close the descriptor but initiates
96 the following closing sequence:
97
98 \par
99 -# The descriptor is placed in a "closing" state.
100 -# The registered read, write, and accept callbacks (if any) are
101 scheduled (in an unspecified order).
102 -# The close callbacks are scheduled (in an unspecified order).
103 -# A call to the internal descriptor closing handler is
104 scheduled.
105
106 \par
107 The "unspecified" order above means that the user should not rely on
108 any specific or deterministic order because the currently hard-coded
109 order may change.
110
111 \par
112 The read, write, and accept notifications (scheduled in step #2
c8407295
AJ
113 above) carry the Comm::ERR_CLOSING error flag. When handling
114 Comm::ERR_CLOSING event, the user code should limit
946b016d
AR
115 descriptor-related processing, especially Comm calls, because
116 supported Comm functionality is very limited when the descriptor is
117 closing. New code should use the close handlers instead (scheduled
118 in step #3).
119
120 \par
121 The internal closing handler (scheduled in step #4 above) closes the
122 descriptor. When the descriptor is closed, all operations on the
123 descriptor are prohibited and may cause bugs and asserts. Currently,
124 the same descriptor will eventually be reused for another socket and
125 Comm may not notice that a buggy code is still using a stale
126 descriptor, but that may change.
127
128 \par
129 Since all notifications are asynchronous, it is possible for a read
130 or write notification that was scheduled before comm_close() was
131 called to arrive at its destination after comm_close() was called.
c8407295 132 Such notification will arrive with Comm::ERR_CLOSING flag even though
946b016d
AR
133 that flag was not set at the time of the I/O (and the I/O may have
134 been successful). This behavior may change.
135
136
137\section Future Anticipated changes and preparation recommendations
138
139 \par
140 This section lists anticipated Comm API changes and provides
141 recommendations for developers writing new (or rewriting old) Comm
142 user code. The changes are listed in a rough order from more likely
143 to less certain and from near-feature to long-term.
144
145 \par
146 The old comm_read_cancel() function that uses a function pointer will be
147 removed as unreliable. Use the AsyncCall-based comm_read_cancel()
148 instead.
149
150 \par
c8407295 151 Comm::ERR_CLOSING interface will be removed. The read, write, and
946b016d
AR
152 accept notifications will not be scheduled after comm_close() is
153 called. New user code should register close handlers instead.
154
155 \par
c8407295 156 When Comm::ERR_CLOSING interface is removed, pending notifications
946b016d
AR
157 (if any) will be canceled after comm_close() is called. However, the
158 cancellation may be removed later if Comm is modified to provide safe
159 access to closing descriptors and their fragile state. New user code
160 should continue to assume that it is safe to access Comm in a read,
161 write, and accept handlers.
162
163 \par
164 The old comm_read_cancel() call that uses a function pointer will be
165 removed as unreliable. New user code should use comm_read_cancel() with
166 an AsyncCall parameter.
167
168 \par
169 Comm users may be required to become children of Comm-provided
170 classes, to eliminate the need for a complicated (albeit hidden)
171 hierarchy of Comm callback dialers (see CommCalls.h) and to provide
172 default implementation for common I/O handling cases. New user code
173 should use methods of AsyncJob-derived classes to handle Comm
174 notifications instead of using stand-alone functions. Additionally, it
175 should not call comm_close() for descriptors it does not "own".
176
177 \par
178 The comm_close() API will be used exclusively for "stop future I/O,
179 schedule a close callback call, and cancel all other callbacks"
180 purposes. New user code should not use comm_close() for the purpose of
181 immediately ending a job.
182
183 \par
184 Raw socket descriptors will be replaced with unique IDs or small
185 objects that help detect stale descriptor/socket usage bugs and
186 encapsulate access to socket-specific information. New user code
187 should treat descriptor integers as opaque objects.
188
189
190 */