Skip to content

Commit

Permalink
[tcp layer] avoid locking and events while shutdown
Browse files Browse the repository at this point in the history
Upon shutdown, when all the TCP conns are destroyed, do not use any locking (we are in single process mode any how) and do not raise any disconnect events (false events here)

(cherry picked from commit f953b30)
  • Loading branch information
bogdan-iancu committed Feb 2, 2023
1 parent cf593ab commit 1a104d6
Showing 1 changed file with 19 additions and 19 deletions.
38 changes: 19 additions & 19 deletions net/net_tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -692,7 +692,7 @@ void tcp_disconnect_event_raise(struct tcp_connection* c)
}

/*! \brief unsafe tcpconn_rm version (nolocks) */
static void _tcpconn_rm(struct tcp_connection* c)
static void _tcpconn_rm(struct tcp_connection* c, int no_event)
{
int r;

Expand All @@ -714,7 +714,7 @@ static void _tcpconn_rm(struct tcp_connection* c)
if (protos[c->type].net.conn_clean)
protos[c->type].net.conn_clean(c);

tcp_disconnect_event_raise(c);
if (!no_event) tcp_disconnect_event_raise(c);

#ifdef DBG_TCPCON
sh_log(c->hist, TCP_DESTROY, "type=%d", c->type);
Expand Down Expand Up @@ -987,7 +987,7 @@ int tcp_conn_send(struct tcp_connection *c)
error:
/* no reporting as closed, as PROTO layer did not reporte it as
* OPEN yet */
_tcpconn_rm(c);
_tcpconn_rm(c,1);
tcp_connections_no--;
return -1;
}
Expand All @@ -1007,7 +1007,7 @@ static inline void tcpconn_destroy(struct tcp_connection* tcpconn)
/* no reporting here - the tcpconn_destroy() function is called
* from the TCP_MAIN reactor when handling connectioned received
* from a worker; and we generate the CLOSE reports from WORKERs */
_tcpconn_rm(tcpconn);
_tcpconn_rm(tcpconn,0);
if (fd >= 0)
close(fd);
tcp_connections_no--;
Expand Down Expand Up @@ -1093,7 +1093,7 @@ static inline int handle_new_connect(struct socket_info* si)
if (tcpconn->refcnt==0){
/* no close to report here as the connection was not yet
* reported as OPEN by the proto layer...this sucks a bit */
_tcpconn_rm(tcpconn);
_tcpconn_rm(tcpconn,1);
close(new_sock/*same as tcpconn->s*/);
}else tcpconn->lifetime=0; /* force expire */
TCPCONN_UNLOCK(id);
Expand Down Expand Up @@ -1144,7 +1144,7 @@ inline static int handle_tcpconn_ev(struct tcp_connection* tcpconn, int fd_i,
fd=tcpconn->s;
tcp_trigger_report(tcpconn, TCP_REPORT_CLOSE,
"No worker for read");
_tcpconn_rm(tcpconn);
_tcpconn_rm(tcpconn,0);
close(fd);
}else tcpconn->lifetime=0; /* force expire*/
TCPCONN_UNLOCK(id);
Expand Down Expand Up @@ -1209,7 +1209,7 @@ inline static int handle_tcpconn_ev(struct tcp_connection* tcpconn, int fd_i,
fd=tcpconn->s;
tcp_trigger_report(tcpconn, TCP_REPORT_CLOSE,
"No worker for write");
_tcpconn_rm(tcpconn);
_tcpconn_rm(tcpconn,0);
close(fd);
}else tcpconn->lifetime=0; /* force expire*/
TCPCONN_UNLOCK(id);
Expand Down Expand Up @@ -1555,13 +1555,13 @@ inline static int handle_io(struct fd_map* fm, int idx,int event_type)
* iterates through all TCP connections and closes expired ones
* Note: runs once per second at most
*/
#define tcpconn_lifetime(last_sec, close_all) \
#define tcpconn_lifetime(last_sec) \
do { \
int now; \
now = get_ticks(); \
if (last_sec != now) { \
last_sec = now; \
__tcpconn_lifetime(close_all); \
__tcpconn_lifetime(0); \
} \
} while (0)

Expand All @@ -1571,7 +1571,7 @@ inline static int handle_io(struct fd_map* fm, int idx,int event_type)
* the same except for io_watch_del..
* \todo FIXME (very inefficient for now)
*/
static inline void __tcpconn_lifetime(int force)
static inline void __tcpconn_lifetime(int shutdown)
{
struct tcp_connection *c, *next;
unsigned int ticks,part;
Expand All @@ -1584,25 +1584,25 @@ static inline void __tcpconn_lifetime(int force)
ticks=0;

for( part=0 ; part<TCP_PARTITION_SIZE ; part++ ) {
TCPCONN_LOCK(part); /* fixme: we can lock only on delete IMO */
if (!shutdown) TCPCONN_LOCK(part); /* fixme: we can lock only on delete IMO */
for(h=0; h<TCP_ID_HASH_SIZE; h++){
c=TCP_PART(part).tcpconn_id_hash[h];
while(c){
next=c->id_next;
if (force ||((c->refcnt==0) && (ticks>c->lifetime))) {
if (!force)
if (shutdown ||((c->refcnt==0) && (ticks>c->lifetime))) {
if (!shutdown)
LM_DBG("timeout for hash=%d - %p"
" (%d > %d)\n", h, c, ticks, c->lifetime);
fd=c->s;
/* report the closing of the connection . Note that
* there are connectioned that use an foced expire to 0
* as a way to be deleted - we are not interested in */
/* Also, do not trigger reporting when shutdown (force=1)
/* Also, do not trigger reporting when shutdown
* is done */
if (c->lifetime>0 && !force)
if (c->lifetime>0 && !shutdown)
tcp_trigger_report(c, TCP_REPORT_CLOSE,
"Timeout on no traffic");
if ((!force)&&(fd>0)&&(c->refcnt==0)) {
if ((!shutdown)&&(fd>0)&&(c->refcnt==0)) {
/* if any of read or write are set, we need to remove
* the fd from the reactor */
if ((c->flags & F_CONN_REMOVED) != F_CONN_REMOVED){
Expand All @@ -1612,13 +1612,13 @@ static inline void __tcpconn_lifetime(int force)
close(fd);
c->s = -1;
}
_tcpconn_rm(c);
_tcpconn_rm(c, shutdown?1:0);
tcp_connections_no--;
}
c=next;
}
}
TCPCONN_UNLOCK(part);
if (!shutdown) TCPCONN_UNLOCK(part);
}
}

Expand Down Expand Up @@ -1700,7 +1700,7 @@ static void tcp_main_server(void)

/* main loop (requires "handle_io()" implementation) */
reactor_main_loop( TCP_MAIN_SELECT_TIMEOUT, error,
tcpconn_lifetime(last_sec, 0) );
tcpconn_lifetime(last_sec) );

error:
destroy_worker_reactor();
Expand Down

0 comments on commit 1a104d6

Please sign in to comment.