]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
UPnP: add delay handling to write queue
authorJaroslav Kysela <perex@perex.cz>
Thu, 12 Feb 2015 20:46:27 +0000 (21:46 +0100)
committerJaroslav Kysela <perex@perex.cz>
Wed, 11 Mar 2015 20:41:12 +0000 (21:41 +0100)
src/input/mpegts/satip/satip.c
src/upnp.c
src/upnp.h

index 9962c424603b509ae5c0ba46871f64a82b880da9..1d1c5eff54e71035d3ed1ba8f473c985182f2bb5 100644 (file)
@@ -976,7 +976,7 @@ ST: urn:ses-com:device:SatIPServer:1\r\n"
   htsbuf_append(&q, MSG, sizeof(MSG)-1);
   htsbuf_qprintf(&q, "USER-AGENT: unix/1.0 UPnP/1.1 TVHeadend/%s\r\n", tvheadend_version);
   htsbuf_append(&q, "\r\n", 2);
-  upnp_send(&q, NULL);
+  upnp_send(&q, NULL, 0);
   htsbuf_queue_flush(&q);
 
   gtimer_arm_ms(&satip_discovery_msearch_timer, satip_discovery_send_msearch,
index 7d8c1ab8266faa2f610b081ca68df599c40066e5..95747459ef859838e90e4fa67c7ada0dddfd01d4 100644 (file)
@@ -49,6 +49,7 @@ typedef struct upnp_data {
   TAILQ_ENTRY(upnp_data) data_link;
   struct sockaddr_storage storage;
   htsbuf_queue_t queue;
+  int delay_ms;
 } upnp_data_t;
 
 TAILQ_HEAD(upnp_data_queue_write, upnp_data);
@@ -81,7 +82,7 @@ void upnp_service_destroy( upnp_service_t *us )
  *
  */
 void
-upnp_send( htsbuf_queue_t *q, struct sockaddr_storage *storage )
+upnp_send( htsbuf_queue_t *q, struct sockaddr_storage *storage, int delay_ms )
 {
   upnp_data_t *data;
 
@@ -94,6 +95,7 @@ upnp_send( htsbuf_queue_t *q, struct sockaddr_storage *storage )
     data->storage = upnp_ipv4_multicast;
   else
     data->storage = *storage;
+  data->delay_ms = delay_ms;
   pthread_mutex_lock(&upnp_lock);
   TAILQ_INSERT_TAIL(&upnp_data_write, data, data_link);
   pthread_mutex_unlock(&upnp_lock);
@@ -116,7 +118,7 @@ upnp_thread( void *aux )
   struct sockaddr_storage ip;
   socklen_t iplen;
   size_t size;
-  int r;
+  int r, delay_ms;
 
   multicast = udp_bind("upnp", "upnp_thread_multicast",
                        "239.255.255.250", 1900,
@@ -137,8 +139,12 @@ upnp_thread( void *aux )
   ev[1].data.ptr = unicast;
   tvhpoll_add(poll, ev, 2);
 
+  delay_ms = 0;
+
   while (upnp_running && multicast->fd >= 0) {
-    r = tvhpoll_wait(poll, ev, 2, 1000);
+    r = tvhpoll_wait(poll, ev, 2, delay_ms ?: 1000);
+    if (r == 0) /* timeout */
+      delay_ms = 0;
 
     while (r-- > 0) {
       if ((ev[r].events & TVHPOLL_IN) != 0) {
@@ -162,20 +168,43 @@ upnp_thread( void *aux )
       }
     }
 
-    while (1) {
+    while (delay_ms == 0) {
       pthread_mutex_lock(&upnp_lock);
       data = TAILQ_FIRST(&upnp_data_write);
-      if (data)
-        TAILQ_REMOVE(&upnp_data_write, data, data_link);
+      if (data) {
+        delay_ms = data->delay_ms;
+        data->delay_ms = 0;
+        if (!delay_ms) {
+          TAILQ_REMOVE(&upnp_data_write, data, data_link);
+        } else {
+          data = NULL;
+        }
+      }
       pthread_mutex_unlock(&upnp_lock);
       if (data == NULL)
         break;
       udp_write_queue(unicast, &data->queue, &data->storage);
       htsbuf_queue_flush(&data->queue);
       free(data);
+      delay_ms = 0;
     }
   }
 
+  /* flush the write queue (byebye messages) */
+  while (1) {
+    pthread_mutex_lock(&upnp_lock);
+    data = TAILQ_FIRST(&upnp_data_write);
+    if (data)
+      TAILQ_REMOVE(&upnp_data_write, data, data_link);
+    pthread_mutex_unlock(&upnp_lock);
+    if (data == NULL)
+      break;
+    usleep((long)data->delay_ms * 1000);
+    udp_write_queue(unicast, &data->queue, &data->storage);
+    htsbuf_queue_flush(&data->queue);
+    free(data);
+  }
+
 error:
   upnp_running = 0;
   tvhpoll_destroy(poll);
index 7753e430c607f2e399c8be58805f262877efc6fa..87864829118a7b9ee5e110e612fc169c934d93f9 100644 (file)
@@ -39,7 +39,7 @@ upnp_service_t *upnp_service_create0(upnp_service_t *us);
   upnp_service_create0(calloc(1, sizeof(struct us)))
 void upnp_service_destroy(upnp_service_t *service);
 
-void upnp_send(htsbuf_queue_t *q, struct sockaddr_storage *storage);
+void upnp_send(htsbuf_queue_t *q, struct sockaddr_storage *storage, int delay_ms);
 
 void upnp_server_init(const char *bindaddr);
 void upnp_server_done(void);