@@ -89,8 +89,21 @@ class Connector
8989 std::set<Connection<BUFFER, NetProvider>> m_ReadyToSend;
9090 void close (Connection<BUFFER, NetProvider> &conn);
9191 void close (ConnectionImpl<BUFFER, NetProvider> &conn);
92+ private:
93+ /* *
94+ * A helper to decode responses of a connection.
95+ * Can be called when the connection is not ready to decode - it's just no-op.
96+ * Returns -1 in the case of any error, 0 on success.
97+ */
98+ int connectionDecodeResponses (Connection<BUFFER, NetProvider> &conn,
99+ Response<BUFFER> *result);
92100private:
93101 NetProvider m_NetProvider;
102+ /* *
103+ * Set of connections that are ready to decode.
104+ * Shouldn't be modified directly - is managed by methods `readyToDecode`
105+ * and `connectionDecodeResponses`.
106+ */
94107 std::set<Connection<BUFFER, NetProvider>> m_ReadyToDecode;
95108};
96109
@@ -157,21 +170,35 @@ Connector<BUFFER, NetProvider>::close(ConnectionImpl<BUFFER, NetProvider> &conn)
157170
158171template <class BUFFER , class NetProvider >
159172int
160- connectionDecodeResponses (Connection<BUFFER, NetProvider> &conn,
161- Response<BUFFER> *result)
173+ Connector<BUFFER, NetProvider>:: connectionDecodeResponses(Connection<BUFFER, NetProvider> &conn,
174+ Response<BUFFER> *result)
162175{
176+ if (!hasDataToDecode (conn))
177+ return 0 ;
178+
179+ /* Ready to decode connection must be in the corresponding set. */
180+ assert (m_ReadyToDecode.find (conn) != m_ReadyToDecode.end ());
181+
182+ int rc = 0 ;
163183 while (hasDataToDecode (conn)) {
164- DecodeStatus rc = processResponse (conn, result);
165- if (rc == DECODE_ERR)
166- return -1 ;
184+ DecodeStatus status = processResponse (conn, result);
185+ if (status == DECODE_ERR) {
186+ rc = -1 ;
187+ break ;
188+ }
167189 // In case we've received only a part of response
168190 // we should wait until the rest arrives - otherwise
169191 // we can't properly decode response. */
170- if (rc == DECODE_NEEDMORE)
171- return 0 ;
172- assert (rc == DECODE_SUCC);
192+ if (status == DECODE_NEEDMORE) {
193+ rc = 0 ;
194+ break ;
195+ }
196+ assert (status == DECODE_SUCC);
173197 }
174- return 0 ;
198+ /* A connection that has no data to decode must not be left in the set. */
199+ if (!hasDataToDecode (conn))
200+ m_ReadyToDecode.erase (conn);
201+ return rc;
175202}
176203
177204template <class BUFFER , class NetProvider >
@@ -191,17 +218,8 @@ Connector<BUFFER, NetProvider>::wait(Connection<BUFFER, NetProvider> &conn,
191218 strerror (errno), errno);
192219 return -1 ;
193220 }
194- if (hasDataToDecode (conn)) {
195- assert (m_ReadyToDecode.find (conn) != m_ReadyToDecode.end ());
196- if (connectionDecodeResponses (conn, result) != 0 )
197- return -1 ;
198- /*
199- * In case we've handled whole data in input buffer -
200- * mark connection as completed.
201- */
202- if (!hasDataToDecode (conn))
203- m_ReadyToDecode.erase (conn);
204- }
221+ if (connectionDecodeResponses (conn, result) != 0 )
222+ return -1 ;
205223 if (timer.isExpired ())
206224 break ;
207225 }
@@ -233,13 +251,8 @@ Connector<BUFFER, NetProvider>::waitAll(Connection<BUFFER, NetProvider> &conn,
233251 strerror (errno), errno);
234252 return -1 ;
235253 }
236- if (hasDataToDecode (conn)) {
237- assert (m_ReadyToDecode.find (conn) != m_ReadyToDecode.end ());
238- if (connectionDecodeResponses (conn, static_cast <Response<BUFFER>*>(nullptr )) != 0 )
239- return -1 ;
240- if (!hasDataToDecode (conn))
241- m_ReadyToDecode.erase (conn);
242- }
254+ if (connectionDecodeResponses (conn, static_cast <Response<BUFFER>*>(nullptr )) != 0 )
255+ return -1 ;
243256 bool finish = true ;
244257 for (size_t i = last_not_ready; i < futures.size (); ++i) {
245258 if (!conn.futureIsReady (futures[i])) {
@@ -280,8 +293,6 @@ Connector<BUFFER, NetProvider>::waitAny(int timeout)
280293 assert (hasDataToDecode (conn));
281294 if (connectionDecodeResponses (conn, static_cast <Response<BUFFER>*>(nullptr )) != 0 )
282295 return std::nullopt ;
283- if (!hasDataToDecode (conn))
284- m_ReadyToDecode.erase (conn);
285296 return conn;
286297}
287298
@@ -299,13 +310,8 @@ Connector<BUFFER, NetProvider>::waitCount(Connection<BUFFER, NetProvider> &conn,
299310 strerror (errno), errno);
300311 return -1 ;
301312 }
302- if (hasDataToDecode (conn)) {
303- assert (m_ReadyToDecode.find (conn) != m_ReadyToDecode.end ());
304- if (connectionDecodeResponses (conn, static_cast <Response<BUFFER>*>(nullptr )) != 0 )
305- return -1 ;
306- if (!hasDataToDecode (conn))
307- m_ReadyToDecode.erase (conn);
308- }
313+ if (connectionDecodeResponses (conn, static_cast <Response<BUFFER>*>(nullptr )) != 0 )
314+ return -1 ;
309315 if ((conn.getFutureCount () - ready_futures) >= future_count)
310316 return 0 ;
311317 if (timer.isExpired ())
0 commit comments