This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit d0593b9d37797f612d8af65ced004c7336974832 Author: p-szafonimateusz <[email protected]> AuthorDate: Mon Nov 9 11:51:12 2026 +0100 net/can: Move the CAN connection pool to can_raw.c. Each CAN protocol allocates its own connection structure, so move the connection pool and can_alloc()/can_free() to can_raw.c as the static can_raw_alloc()/can_raw_free(). The protocol-independent part moves to can.c: - can_conn_init() initializes the state shared by all CAN protocols (the reference count, the buffer limits, the send semaphore and the socket lock), which was done in can_raw_setup(), and adds the connection to the list of active connections. - can_conn_uninit() removes the connection from the list and releases the shared state. The list of active connections gets its own recursive mutex instead of the lock of the connection pool, because the pool now belongs to the protocol. No functional change. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: p-szafonimateusz <[email protected]> --- net/can/can.c | 105 ++++++++++++++++++++-------------------------- net/can/can.h | 17 ++++---- net/can/can_raw.c | 123 +++++++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 153 insertions(+), 92 deletions(-) diff --git a/net/can/can.c b/net/can/can.c index cd564de8974..068f06db748 100644 --- a/net/can/can.c +++ b/net/can/can.c @@ -53,28 +53,19 @@ #include "devif/devif.h" #include "utils/utils.h" -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -#ifndef CONFIG_NET_CAN_MAX_CONNS -# define CONFIG_NET_CAN_MAX_CONNS 0 -#endif - /**************************************************************************** * Private Data ****************************************************************************/ -/* The array containing all NetLink connections. */ +/* A list of all allocated CAN connections */ -NET_BUFPOOL_DECLARE(g_can_connections, sizeof(struct can_conn_s), - CONFIG_NET_CAN_PREALLOC_CONNS, - CONFIG_NET_CAN_ALLOC_CONNS, - CONFIG_NET_CAN_MAX_CONNS); +static dq_queue_t g_active_can_connections; -/* A list of all allocated NetLink connections */ +/* Protects g_active_can_connections. Recursive because can_input() holds + * it while it looks up the destination connections. + */ -static dq_queue_t g_active_can_connections; +static rmutex_t g_can_conn_lock = NXRMUTEX_INITIALIZER; /**************************************************************************** * Public Data @@ -616,68 +607,66 @@ void can_readahead_signal(FAR struct can_conn_s *conn) #endif /**************************************************************************** - * Name: can_alloc() + * Name: can_conn_init * * Description: - * Allocate a new, uninitialized NetLink connection structure. This is - * normally something done by the implementation of the socket() API + * Initialize the state shared by all CAN protocols in a newly allocated + * connection and add it to the list of active connections. + * + * Input Parameters: + * conn - The connection to initialize * ****************************************************************************/ -FAR struct can_conn_s *can_alloc(void) +void can_conn_init(FAR struct can_conn_s *conn) { - FAR struct can_conn_s *conn; - - /* The free list is protected by a a mutex. */ + /* Set the reference count on the connection structure. This + * reference count will be incremented only if the socket is + * dup'ed + */ - NET_BUFPOOL_LOCK(g_can_connections); + conn->crefs = 1; - conn = NET_BUFPOOL_TRYALLOC(g_can_connections); - if (conn != NULL) - { - /* FIXME SocketCAN default behavior enables loopback */ - -#ifdef CONFIG_NET_CANPROTO_OPTIONS - /* By default the filter is configured to catch all, - * this is done in commented filter code below: - * - * struct can_filter_t catchall_filter; - * filter.can_id = 0; - * filter.can_mask = 0; - * conn->filters[0] = catchall_filter; - * - * However memset already sets the filter to 0 - * therefore we only have to set the filter count to 1 - */ + /* If Can Socket Stack receive can frame and pending on the readahead, + * but the application layer did not read the frame. This will cause + * a memory leak, and it is necessary to limit the readahead. + */ - conn->filter_count = 1; +#if CONFIG_NET_RECV_BUFSIZE > 0 + conn->rcvbufs = CONFIG_NET_RECV_BUFSIZE; #endif - /* Enqueue the connection into the active list */ +#if CONFIG_NET_SEND_BUFSIZE > 0 + conn->sndbufs = CONFIG_NET_SEND_BUFSIZE; + nxsem_init(&conn->sndsem, 0, 0); +#endif + nxrmutex_init(&conn->sconn.s_lock); - dq_addlast(&conn->sconn.node, &g_active_can_connections); - } + /* Enqueue the connection into the active list */ - NET_BUFPOOL_UNLOCK(g_can_connections); - return conn; + can_conn_list_lock(); + dq_addlast(&conn->sconn.node, &g_active_can_connections); + can_conn_list_unlock(); } /**************************************************************************** - * Name: can_free() + * Name: can_conn_uninit * * Description: - * Free a NetLink connection structure that is no longer in use. This - * should be done by the implementation of close(). + * Remove a connection from the list of active connections and release + * the state shared by all CAN protocols. The caller frees the + * connection itself. + * + * Input Parameters: + * conn - The connection to uninitialize * ****************************************************************************/ -void can_free(FAR struct can_conn_s *conn) +void can_conn_uninit(FAR struct can_conn_s *conn) { - /* The free list is protected by a mutex. */ - DEBUGASSERT(conn->crefs == 0); - NET_BUFPOOL_LOCK(g_can_connections); + can_conn_list_lock(); /* Remove the connection from the active list */ @@ -705,11 +694,7 @@ void can_free(FAR struct can_conn_s *conn) iob_free_queue(&conn->readahead); - /* Free the connection. */ - - NET_BUFPOOL_FREE(g_can_connections, conn); - - NET_BUFPOOL_UNLOCK(g_can_connections); + can_conn_list_unlock(); } /**************************************************************************** @@ -803,12 +788,12 @@ FAR struct can_conn_s *can_conn_next(FAR struct can_conn_s *conn) void can_conn_list_lock(void) { - NET_BUFPOOL_LOCK(g_can_connections); + nxrmutex_lock(&g_can_conn_lock); } void can_conn_list_unlock(void) { - NET_BUFPOOL_UNLOCK(g_can_connections); + nxrmutex_unlock(&g_can_conn_lock); } /**************************************************************************** diff --git a/net/can/can.h b/net/can/can.h index 91318a71cf9..45a4f63b3fd 100644 --- a/net/can/can.h +++ b/net/can/can.h @@ -162,26 +162,27 @@ FAR const struct sock_intf_s * can_sockif(sa_family_t family, int type, int protocol); /**************************************************************************** - * Name: can_alloc() + * Name: can_conn_init * * Description: - * Allocate a new, uninitialized NetLink connection structure. This is - * normally something done by the implementation of the socket() API + * Initialize the state shared by all CAN protocols in a newly allocated + * connection and add it to the list of active connections. * ****************************************************************************/ -FAR struct can_conn_s *can_alloc(void); +void can_conn_init(FAR struct can_conn_s *conn); /**************************************************************************** - * Name: can_free() + * Name: can_conn_uninit * * Description: - * Free a NetLink connection structure that is no longer in use. This - * should be done by the implementation of close(). + * Remove a connection from the list of active connections and release + * the state shared by all CAN protocols. The caller frees the + * connection itself. * ****************************************************************************/ -void can_free(FAR struct can_conn_s *conn); +void can_conn_uninit(FAR struct can_conn_s *conn); /**************************************************************************** * Name: can_conn_bind diff --git a/net/can/can_raw.c b/net/can/can_raw.c index 2cf1d5a2f1d..dacfa507d40 100644 --- a/net/can/can_raw.c +++ b/net/can/can_raw.c @@ -45,12 +45,15 @@ #include <netpacket/packet.h> #include <nuttx/debug.h> #include <nuttx/kmalloc.h> +#include <nuttx/mutex.h> #include <nuttx/net/can.h> #include <nuttx/net/ip.h> #include <nuttx/net/net.h> +#include <nuttx/net/netconfig.h> #include <nuttx/net/netdev.h> #include <nuttx/net/netstats.h> #include <nuttx/poll.h> +#include <nuttx/queue.h> #include <nuttx/semaphore.h> #include <nuttx/wqueue.h> @@ -60,6 +63,14 @@ #include "socket/socket.h" #include "utils/utils.h" +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_NET_CAN_MAX_CONNS +# define CONFIG_NET_CAN_MAX_CONNS 0 +#endif + /**************************************************************************** * Private Types ****************************************************************************/ @@ -120,6 +131,17 @@ static int can_raw_setsockopt(FAR struct socket *psock, int level, socklen_t value_len); #endif +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* The array containing all CAN_RAW connections. */ + +NET_BUFPOOL_DECLARE(g_can_raw_connections, sizeof(struct can_conn_s), + CONFIG_NET_CAN_PREALLOC_CONNS, + CONFIG_NET_CAN_ALLOC_CONNS, + CONFIG_NET_CAN_MAX_CONNS); + /**************************************************************************** * Public Data ****************************************************************************/ @@ -152,6 +174,81 @@ const struct sock_intf_s g_can_raw_sockif = * Private Functions ****************************************************************************/ +/**************************************************************************** + * Name: can_raw_alloc() + * + * Description: + * Allocate a new, uninitialized NetLink connection structure. This is + * normally something done by the implementation of the socket() API + * + ****************************************************************************/ + +static FAR struct can_conn_s *can_raw_alloc(void) +{ + FAR struct can_conn_s *conn; + + /* The free list is protected by a a mutex. */ + + NET_BUFPOOL_LOCK(g_can_raw_connections); + + conn = NET_BUFPOOL_TRYALLOC(g_can_raw_connections); + if (conn != NULL) + { + /* FIXME SocketCAN default behavior enables loopback */ + +#ifdef CONFIG_NET_CANPROTO_OPTIONS + /* By default the filter is configured to catch all, + * this is done in commented filter code below: + * + * struct can_filter_t catchall_filter; + * filter.can_id = 0; + * filter.can_mask = 0; + * conn->filters[0] = catchall_filter; + * + * However memset already sets the filter to 0 + * therefore we only have to set the filter count to 1 + */ + + conn->filter_count = 1; +#endif + + /* Initialize the shared state and enqueue the connection into the + * active list + */ + + can_conn_init(conn); + } + + NET_BUFPOOL_UNLOCK(g_can_raw_connections); + return conn; +} + +/**************************************************************************** + * Name: can_raw_free() + * + * Description: + * Free a NetLink connection structure that is no longer in use. This + * should be done by the implementation of close(). + * + ****************************************************************************/ + +static void can_raw_free(FAR struct can_conn_s *conn) +{ + /* The free list is protected by a mutex. */ + + DEBUGASSERT(conn->crefs == 0); + + NET_BUFPOOL_LOCK(g_can_raw_connections); + + can_conn_uninit(conn); + + /* Free the connection. */ + + NET_BUFPOOL_FREE(g_can_raw_connections, conn); + + NET_BUFPOOL_UNLOCK(g_can_raw_connections); +} + /**************************************************************************** * Name: can_recvfrom_initialize * @@ -1865,7 +1962,7 @@ static int can_raw_setup(FAR struct socket *psock) * new socket instance. */ - FAR struct can_conn_s *conn = can_alloc(); + FAR struct can_conn_s *conn = can_raw_alloc(); if (conn == NULL) { @@ -1874,28 +1971,6 @@ static int can_raw_setup(FAR struct socket *psock) return -ENOMEM; } - /* Set the reference count on the connection structure. This - * reference count will be incremented only if the socket is - * dup'ed - */ - - conn->crefs = 1; - - /* If Can Socket Stack receive can frame and pending on the readahead, - * but the application layer did not read the frame. This will cause - * a memory leak, and it is necessary to limit the readahead. - */ - -#if CONFIG_NET_RECV_BUFSIZE > 0 - conn->rcvbufs = CONFIG_NET_RECV_BUFSIZE; -#endif - -#if CONFIG_NET_SEND_BUFSIZE > 0 - conn->sndbufs = CONFIG_NET_SEND_BUFSIZE; - nxsem_init(&conn->sndsem, 0, 0); -#endif - nxrmutex_init(&conn->sconn.s_lock); - #ifdef CONFIG_NET_CANPROTO_OPTIONS /* By default loopback is enabled */ @@ -2239,7 +2314,7 @@ static int can_raw_close(FAR struct socket *psock) /* Free the connection structure */ conn->crefs = 0; - can_free(psock->s_conn); + can_raw_free(psock->s_conn); if (ret < 0) {
