/** Add a connection to the list of connections with queued data. * @param[in] con Connection with queued data. * @param[in,out] con_p Previous pointer to next connection. */ void client_add_sendq(struct Connection* con, struct Connection** con_p) { if (!con_prev_p(con)) { /* not on the queued data list yet... */ con_prev_p(con) = con_p; con_next(con) = *con_p; if (*con_p) con_prev_p(*con_p) = &(con_next(con)); *con_p = con; } }
/** Remove a connection from the list of connections with queued data. * @param[in] con Connection with no queued data. */ void client_drop_sendq(struct Connection* con) { if (con_prev_p(con)) { /* on the queued data list... */ if (con_next(con)) con_prev_p(con_next(con)) = con_prev_p(con); *(con_prev_p(con)) = con_next(con); con_next(con) = 0; con_prev_p(con) = 0; } }
/** Release a Connection and all memory associated with it. * The connection's DNS reply field is freed, its file descriptor is * closed, its msgq and sendq are cleared, and its associated Listener * is dereferenced. Then it is prepended to #connectionFreeList. * @param[in] con Connection to free. */ static void dealloc_connection(struct Connection* con) { assert(con_verify(con)); assert(!t_active(&(con_proc(con)))); assert(!t_onqueue(&(con_proc(con)))); Debug((DEBUG_LIST, "Deallocating connection %p", con)); if (con_dns_reply(con)) --(con_dns_reply(con)->ref_count); if (con_dnsbl_reply(con)) --(con_dnsbl_reply(con)->ref_count); if (-1 < con_fd(con)) close(con_fd(con)); MsgQClear(&(con_sendQ(con))); client_drop_sendq(con); DBufClear(&(con_recvQ(con))); if (con_listener(con)) release_listener(con_listener(con)); if (con_loc(con)) MyFree(con_loc(con)); --connections.inuse; con_next(con) = connectionFreeList; connectionFreeList = con; con_magic(con) = 0; }
void init_list(void) { struct Client* cptr; struct Connection* con; int i; /* * pre-allocate MAXCONNECTIONS clients and connections */ for (i = 0; i < MAXCONNECTIONS; ++i) { cptr = (struct Client*) MyMalloc(sizeof(struct Client)); cli_next(cptr) = clientFreeList; clientFreeList = cptr; ++clientAllocCount; con = (struct Connection*) MyMalloc(sizeof(struct Connection)); con_next(con) = connectionFreeList; connectionFreeList = con; ++connectionAllocCount; } #ifdef DEBUGMODE memset(&clients, 0, sizeof(clients)); memset(&connections, 0, sizeof(connections)); memset(&users, 0, sizeof(users)); memset(&servs, 0, sizeof(servs)); memset(&links, 0, sizeof(links)); #endif }
/** Flush data queued for one or all connections. * @param[in] cptr Client to flush (if NULL, do all). */ void flush_connections(struct Client* cptr) { if (cptr) { send_queued(cptr); } else { struct Connection* con; for (con = send_queues; con; con = con_next(con)) { assert(0 < MsgQLength(&(con_sendQ(con)))); send_queued(con_client(con)); } } }
/** Allocate a new Connection structure. * If #connectionFreeList != NULL, use the head of that list. * Otherwise, allocate a new structure. * @return Newly allocated Connection. */ static struct Connection* alloc_connection(void) { struct Connection* con = connectionFreeList; if (!con) { con = (struct Connection*) MyMalloc(sizeof(struct Connection)); connections.alloc++; } else connectionFreeList = con_next(con); connections.inuse++; memset(con, 0, sizeof(struct Connection)); timer_init(&(con_proc(con))); return con; }
static struct Connection* alloc_connection(void) { struct Connection* con = connectionFreeList; if (!con) { con = (struct Connection*) MyMalloc(sizeof(struct Connection)); ++connectionAllocCount; } else connectionFreeList = con_next(con); #ifdef DEBUGMODE connections.inuse++; #endif memset(con, 0, sizeof(struct Connection)); timer_init(&(con_proc(con))); return con; }
/** Initialize the list manipulation support system. * Pre-allocate MAXCONNECTIONS Client and Connection structures. */ void init_list(void) { struct Client* cptr; struct Connection* con; int i; /* * pre-allocate MAXCONNECTIONS clients and connections */ for (i = 0; i < MAXCONNECTIONS; ++i) { cptr = (struct Client*) MyMalloc(sizeof(struct Client)); cli_next(cptr) = clientFreeList; clientFreeList = cptr; clients.alloc++; con = (struct Connection*) MyMalloc(sizeof(struct Connection)); con_next(con) = connectionFreeList; connectionFreeList = con; connections.alloc++; } }