REORG: connection: uninline the rest of the alloc/free stuff

The remaining large functions are those allocating/initializing and
occasionally freeing connections, conn_streams and sockaddr. Let's
move them to connection.c. In fact, cs_free() is the only one-liner
but let's move it along with the other ones since a call will be
small compared to the rest of the work done there.
This commit is contained in:
Willy Tarreau 2021-10-06 19:11:10 +02:00
parent 7969986c2c
commit 8de90c71b3
2 changed files with 90 additions and 85 deletions

View File

@ -31,7 +31,7 @@
#include <haproxy/list.h> #include <haproxy/list.h>
#include <haproxy/listener-t.h> #include <haproxy/listener-t.h>
#include <haproxy/obj_type.h> #include <haproxy/obj_type.h>
#include <haproxy/pool.h> #include <haproxy/pool-t.h>
#include <haproxy/server.h> #include <haproxy/server.h>
#include <haproxy/session-t.h> #include <haproxy/session-t.h>
#include <haproxy/task-t.h> #include <haproxy/task-t.h>
@ -86,6 +86,12 @@ void conn_delete_from_tree(struct ebmb_node *node);
void conn_init(struct connection *conn, void *target); void conn_init(struct connection *conn, void *target);
struct connection *conn_new(void *target); struct connection *conn_new(void *target);
void conn_free(struct connection *conn); void conn_free(struct connection *conn);
struct conn_hash_node *conn_alloc_hash_node(struct connection *conn);
struct sockaddr_storage *sockaddr_alloc(struct sockaddr_storage **sap, const struct sockaddr_storage *orig, socklen_t len);
void sockaddr_free(struct sockaddr_storage **sap);
void cs_free(struct conn_stream *cs);
struct conn_stream *cs_new(struct connection *conn, void *target);
/* connection hash stuff */ /* connection hash stuff */
uint64_t conn_calculate_hash(const struct conn_hash_params *params); uint64_t conn_calculate_hash(const struct conn_hash_params *params);
@ -332,19 +338,6 @@ static inline int conn_is_back(const struct connection *conn)
return !objt_listener(conn->target); return !objt_listener(conn->target);
} }
static inline struct conn_hash_node *conn_alloc_hash_node(struct connection *conn)
{
struct conn_hash_node *hash_node = NULL;
hash_node = pool_zalloc(pool_head_conn_hash_node);
if (unlikely(!hash_node))
return NULL;
hash_node->conn = conn;
return hash_node;
}
/* sets <owner> as the connection's owner */ /* sets <owner> as the connection's owner */
static inline void conn_set_owner(struct connection *conn, void *owner, void (*cb)(struct connection *)) static inline void conn_set_owner(struct connection *conn, void *owner, void (*cb)(struct connection *))
{ {
@ -364,77 +357,6 @@ static inline void conn_set_private(struct connection *conn)
} }
} }
/* Allocates a struct sockaddr from the pool if needed, assigns it to *sap and
* returns it. If <sap> is NULL, the address is always allocated and returned.
* if <sap> is non-null, an address will only be allocated if it points to a
* non-null pointer. In this case the allocated address will be assigned there.
* If <orig> is non-null and <len> positive, the address in <sa> will be copied
* into the allocated address. In both situations the new pointer is returned.
*/
static inline struct sockaddr_storage *
sockaddr_alloc(struct sockaddr_storage **sap, const struct sockaddr_storage *orig, socklen_t len)
{
struct sockaddr_storage *sa;
if (sap && *sap)
return *sap;
sa = pool_alloc(pool_head_sockaddr);
if (sa && orig && len > 0)
memcpy(sa, orig, len);
if (sap)
*sap = sa;
return sa;
}
/* Releases the struct sockaddr potentially pointed to by <sap> to the pool. It
* may be NULL or may point to NULL. If <sap> is not NULL, a NULL is placed
* there.
*/
static inline void sockaddr_free(struct sockaddr_storage **sap)
{
if (!sap)
return;
pool_free(pool_head_sockaddr, *sap);
*sap = NULL;
}
/* Releases a conn_stream previously allocated by cs_new(), as well as any
* buffer it would still hold.
*/
static inline void cs_free(struct conn_stream *cs)
{
pool_free(pool_head_connstream, cs);
}
/* Tries to allocate a new conn_stream and initialize its main fields. If
* <conn> is NULL, then a new connection is allocated on the fly, initialized,
* and assigned to cs->conn ; this connection will then have to be released
* using pool_free() or conn_free(). The conn_stream is initialized and added
* to the mux's stream list on success, then returned. On failure, nothing is
* allocated and NULL is returned.
*/
static inline struct conn_stream *cs_new(struct connection *conn, void *target)
{
struct conn_stream *cs;
cs = pool_alloc(pool_head_connstream);
if (unlikely(!cs))
return NULL;
if (!conn) {
conn = conn_new(target);
if (unlikely(!conn)) {
cs_free(cs);
return NULL;
}
}
cs_init(cs, conn);
return cs;
}
/* Retrieves any valid conn_stream from this connection, preferably the first /* Retrieves any valid conn_stream from this connection, preferably the first
* valid one. The purpose is to be able to figure one other end of a private * valid one. The purpose is to be able to figure one other end of a private
* connection for purposes like source binding or proxy protocol header * connection for purposes like source binding or proxy protocol header

View File

@ -437,6 +437,89 @@ void conn_free(struct connection *conn)
pool_free(pool_head_connection, conn); pool_free(pool_head_connection, conn);
} }
struct conn_hash_node *conn_alloc_hash_node(struct connection *conn)
{
struct conn_hash_node *hash_node = NULL;
hash_node = pool_zalloc(pool_head_conn_hash_node);
if (unlikely(!hash_node))
return NULL;
hash_node->conn = conn;
return hash_node;
}
/* Allocates a struct sockaddr from the pool if needed, assigns it to *sap and
* returns it. If <sap> is NULL, the address is always allocated and returned.
* if <sap> is non-null, an address will only be allocated if it points to a
* non-null pointer. In this case the allocated address will be assigned there.
* If <orig> is non-null and <len> positive, the address in <sa> will be copied
* into the allocated address. In both situations the new pointer is returned.
*/
struct sockaddr_storage *sockaddr_alloc(struct sockaddr_storage **sap, const struct sockaddr_storage *orig, socklen_t len)
{
struct sockaddr_storage *sa;
if (sap && *sap)
return *sap;
sa = pool_alloc(pool_head_sockaddr);
if (sa && orig && len > 0)
memcpy(sa, orig, len);
if (sap)
*sap = sa;
return sa;
}
/* Releases the struct sockaddr potentially pointed to by <sap> to the pool. It
* may be NULL or may point to NULL. If <sap> is not NULL, a NULL is placed
* there.
*/
void sockaddr_free(struct sockaddr_storage **sap)
{
if (!sap)
return;
pool_free(pool_head_sockaddr, *sap);
*sap = NULL;
}
/* Releases a conn_stream previously allocated by cs_new(), as well as any
* buffer it would still hold.
*/
void cs_free(struct conn_stream *cs)
{
pool_free(pool_head_connstream, cs);
}
/* Tries to allocate a new conn_stream and initialize its main fields. If
* <conn> is NULL, then a new connection is allocated on the fly, initialized,
* and assigned to cs->conn ; this connection will then have to be released
* using pool_free() or conn_free(). The conn_stream is initialized and added
* to the mux's stream list on success, then returned. On failure, nothing is
* allocated and NULL is returned.
*/
struct conn_stream *cs_new(struct connection *conn, void *target)
{
struct conn_stream *cs;
cs = pool_alloc(pool_head_connstream);
if (unlikely(!cs))
return NULL;
if (!conn) {
conn = conn_new(target);
if (unlikely(!conn)) {
cs_free(cs);
return NULL;
}
}
cs_init(cs, conn);
return cs;
}
/* Try to add a handshake pseudo-XPRT. If the connection's first XPRT is /* Try to add a handshake pseudo-XPRT. If the connection's first XPRT is
* raw_sock, then just use the new XPRT as the connection XPRT, otherwise * raw_sock, then just use the new XPRT as the connection XPRT, otherwise
* call the xprt's add_xprt() method. * call the xprt's add_xprt() method.