bluetooth: host: add asserts to foreach in get_conn_ready
Assert that the previous connection in the list and the tmp element in the loop are different to the current connection. Otherwise, if the same connection was somehow added twice it could result in an infinite loop. Signed-off-by: Ahmed Ahmed <ahmed.ahmed@dewinelabs.com>
This commit is contained in:
parent
099871622a
commit
2edddbddb5
1 changed files with 10 additions and 13 deletions
|
|
@ -912,47 +912,44 @@ struct bt_conn *get_conn_ready(void)
|
||||||
sys_snode_t *prev = NULL;
|
sys_snode_t *prev = NULL;
|
||||||
|
|
||||||
if (dont_have_viewbufs()) {
|
if (dont_have_viewbufs()) {
|
||||||
/* We will get scheduled again when the (view) buffers are freed. If
|
/* We will get scheduled again when the (view) buffers are freed. If you
|
||||||
* you hit this a lot, try increasing `CONFIG_BT_CONN_FRAG_COUNT`
|
* hit this a lot, try increasing `CONFIG_BT_CONN_FRAG_COUNT`
|
||||||
*/
|
*/
|
||||||
LOG_DBG("no view bufs");
|
LOG_DBG("no view bufs");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&bt_dev.le.conn_ready, conn, tmp,
|
SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&bt_dev.le.conn_ready, conn, tmp, _conn_ready) {
|
||||||
_conn_ready) {
|
__ASSERT_NO_MSG(tmp != conn);
|
||||||
|
|
||||||
/* Iterate over the list of connections that have data to send
|
/* Iterate over the list of connections that have data to send
|
||||||
* and return the first one that can be sent.
|
* and return the first one that can be sent.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (cannot_send_to_controller(conn)) {
|
if (cannot_send_to_controller(conn)) {
|
||||||
/* When buffers are full, try next connection.
|
/* When buffers are full, try next connection. */
|
||||||
*/
|
|
||||||
LOG_DBG("no LL bufs for %p", conn);
|
LOG_DBG("no LL bufs for %p", conn);
|
||||||
prev = &conn->_conn_ready;
|
prev = &conn->_conn_ready;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dont_have_tx_context(conn)) {
|
if (dont_have_tx_context(conn)) {
|
||||||
/* When TX contexts are not available, try next connection.
|
/* When TX contexts are not available, try next connection. */
|
||||||
*/
|
|
||||||
LOG_DBG("no TX contexts for %p", conn);
|
LOG_DBG("no TX contexts for %p", conn);
|
||||||
prev = &conn->_conn_ready;
|
prev = &conn->_conn_ready;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECKIF(dont_have_methods(conn)) {
|
CHECKIF(dont_have_methods(conn)) {
|
||||||
/* When a connection is missing mandatory methods, try next
|
/* When a connection is missing mandatory methods, try next connection. */
|
||||||
* connection.
|
LOG_DBG("conn %p (type %d) is missing mandatory methods", conn, conn->type);
|
||||||
*/
|
|
||||||
LOG_DBG("conn %p (type %d) is missing mandatory methods",
|
|
||||||
conn, conn->type);
|
|
||||||
prev = &conn->_conn_ready;
|
prev = &conn->_conn_ready;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (should_stop_tx(conn)) {
|
if (should_stop_tx(conn)) {
|
||||||
/* Move reference off the list */
|
/* Move reference off the list */
|
||||||
|
__ASSERT_NO_MSG(prev != &conn->_conn_ready);
|
||||||
sys_slist_remove(&bt_dev.le.conn_ready, prev, &conn->_conn_ready);
|
sys_slist_remove(&bt_dev.le.conn_ready, prev, &conn->_conn_ready);
|
||||||
(void)atomic_set(&conn->_conn_ready_lock, 0);
|
(void)atomic_set(&conn->_conn_ready_lock, 0);
|
||||||
bt_conn_unref(conn);
|
bt_conn_unref(conn);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue