@ -86,8 +86,11 @@ struct interface_stats_interval {
} ;
} ;
/* thread scope (local) queue for sockets to be released, only appending here */
static __thread GQueue ports_to_release = G_QUEUE_INIT ;
static __thread GQueue ports_to_release = G_QUEUE_INIT ;
/* global queue for sockets to be released, releasing by `sockets_releaser()` is done using that */
static GQueue ports_to_release_glob = G_QUEUE_INIT ;
mutex_t ports_to_release_glob_lock = MUTEX_STATIC_INIT ;
static const struct streamhandler * __determine_handler ( struct packet_stream * in , struct sink_handler * ) ;
static const struct streamhandler * __determine_handler ( struct packet_stream * in , struct sink_handler * ) ;
@ -952,11 +955,49 @@ static void release_port_now(socket_t *r, struct intf_spec *spec) {
ilog ( LOG_WARNING , " Unable to close the socket for port '%u' " , port ) ;
ilog ( LOG_WARNING , " Unable to close the socket for port '%u' " , port ) ;
}
}
}
}
/**
* Sockets releaser .
*/
void release_closed_sockets ( void ) {
void release_closed_sockets ( void ) {
struct late_port_release * lpr ;
while ( ( lpr = g_queue_pop_head ( & ports_to_release ) ) ) {
release_port_now ( & lpr - > socket , lpr - > spec ) ;
g_slice_free1 ( sizeof ( * lpr ) , lpr ) ;
struct late_port_release * lpr ;
/* for the separate releaser thread (one working with `sockets_releaser()`)
* it does no job . But only for those threads related to calls processing .
*/
if ( ports_to_release . head )
append_thread_lpr_to_glob_lpr ( ) ;
if ( ports_to_release_glob . head ) {
mutex_lock ( & ports_to_release_glob_lock ) ;
GQueue ports_left = ports_to_release_glob ;
g_queue_init ( & ports_to_release_glob ) ;
mutex_unlock ( & ports_to_release_glob_lock ) ;
while ( ( lpr = g_queue_pop_head ( & ports_left ) ) ) {
release_port_now ( & lpr - > socket , lpr - > spec ) ;
g_slice_free1 ( sizeof ( * lpr ) , lpr ) ;
}
}
}
/**
* Appends thread scope ( local ) sockets to the global releasing list .
*/
void append_thread_lpr_to_glob_lpr ( void ) {
mutex_lock ( & ports_to_release_glob_lock ) ;
g_queue_move ( & ports_to_release_glob , & ports_to_release ) ; /* dst, src */
mutex_unlock ( & ports_to_release_glob_lock ) ;
}
/**
* Separate thread for releasing sockets scheduled for closing .
*/
void sockets_releaser ( void * dummy ) {
while ( ! rtpe_shutdown ) {
release_closed_sockets ( ) ;
thread_cancel_enable ( ) ;
usleep ( 1000000 ) ; /* sleep for 1 second in each iteration */
thread_cancel_disable ( ) ;
}
}
}
}
@ -3052,7 +3093,6 @@ done:
static void stream_fd_free ( void * p ) {
static void stream_fd_free ( void * p ) {
struct stream_fd * f = p ;
struct stream_fd * f = p ;
release_port ( & f - > socket , f - > local_intf - > spec ) ;
release_port ( & f - > socket , f - > local_intf - > spec ) ;
crypto_cleanup ( & f - > crypto ) ;
crypto_cleanup ( & f - > crypto ) ;
dtls_connection_cleanup ( & f - > dtls ) ;
dtls_connection_cleanup ( & f - > dtls ) ;