From c8128f0cdc138d38f21052362fcf2ec49b890e42 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Thu, 25 Sep 2014 02:34:06 +0200 Subject: timeout for clients --- src/udp.c | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/udp.c b/src/udp.c index 2064e4f..2d352ee 100644 --- a/src/udp.c +++ b/src/udp.c @@ -83,8 +83,9 @@ static void udpsink_add_client(struct sockaddr_storage *addr, socklen_t addrlen, g_get_current_time(&now); client->last_seen_ = GST_TIMEVAL_TO_TIME(now); + GList* entry = g_list_find_custom(sink->clients_, client, cmp_udp_client); gchar* name = gst_element_get_name(sink->udp_); - if(!g_list_find_custom(sink->clients_, client, cmp_udp_client)) { + if(!entry) { log_printf(INFO, "adding host %s%c%d to list of receivers for element %s", client->host_.addr_, client->host_.type_ == IPv4 ? ':' : '.', client->host_.port_, name); g_signal_emit_by_name(G_OBJECT(sink->udp_), "add", client->host_.addr_, client->host_.port_, NULL); @@ -92,6 +93,7 @@ static void udpsink_add_client(struct sockaddr_storage *addr, socklen_t addrlen, } else { log_printf(DEBUG, "not adding host %s%c%d to list of receivers for element %s since it already exists", client->host_.addr_, client->host_.type_ == IPv4 ? ':' : '.', client->host_.port_, name); + ((struct udp_client*)(entry->data))->last_seen_ = client->last_seen_; g_free(client); } g_free(name); @@ -109,9 +111,11 @@ static void udpsink_remove_client(struct sockaddr_storage *addr, socklen_t addrl client->host_.addr_, client->host_.type_ == IPv4 ? ':' : '.', client->host_.port_, name, name); } else { g_signal_emit_by_name(G_OBJECT(sink->udp_), "remove", client->host_.addr_, client->host_.port_, NULL); - log_printf(INFO, "client %s%c%d removed from list of receivers for element %s", + log_printf(INFO, "client %s%c%d removed from list of receivers for element %s (request)", client->host_.addr_, client->host_.type_ == IPv4 ? ':' : '.', client->host_.port_, name, name); + gpointer rdata = removee->data; sink->clients_ = g_list_remove(sink->clients_, removee->data); + g_free(rdata); } g_free(name); g_free(client); @@ -155,10 +159,36 @@ static gboolean on_udp_desc_ready(gint fd, GIOCondition cond, gpointer user_data return TRUE; } -gboolean check_client_timeout(gpointer user_data) +static void check_client_timeout(struct udp_sink* sink, int timeout) +{ + GTimeVal now; + g_get_current_time(&now); + GstClockTime timeout_time = GST_TIMEVAL_TO_TIME(now) - (timeout * GST_SECOND); + + GList *c = sink->clients_; + while(c != NULL) { + GList *next = c->next; + struct udp_client* client = (struct udp_client*)c->data; + if(client->last_seen_ < timeout_time) { + g_signal_emit_by_name(G_OBJECT(sink->udp_), "remove", client->host_.addr_, client->host_.port_, NULL); + gchar* name = gst_element_get_name(sink->udp_); + log_printf(INFO, "client %s%c%d removed from list of receivers for element %s (timeout)", + client->host_.addr_, client->host_.type_ == IPv4 ? ':' : '.', client->host_.port_, name, name); + g_free(name); + g_free(c->data); + sink->clients_ = g_list_delete_link(sink->clients_, c); + } + c = next; + } +} + +static gboolean check_all_client_timeouts(gpointer user_data) { struct udp_sinks* sinks = (struct udp_sinks*)user_data; - log_printf(DEBUG, "******************* checking timeout *******************: %d sec.", sinks->client_timeout_); + check_client_timeout(&(sinks->rtp_video_), sinks->client_timeout_); + check_client_timeout(&(sinks->rtcp_video_), sinks->client_timeout_); + check_client_timeout(&(sinks->rtp_audio_), sinks->client_timeout_); + check_client_timeout(&(sinks->rtcp_audio_), sinks->client_timeout_); return TRUE; } @@ -193,7 +223,7 @@ gboolean attach_udpsinks(struct udp_sinks *sinks) return FALSE; } if(sinks->client_timeout_ > 0) { - if(!g_timeout_add_seconds(1, check_client_timeout, sinks)) + if(!g_timeout_add_seconds(1, check_all_client_timeouts, sinks)) return FALSE; } -- cgit v1.2.3