]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
tcp server: the tcp_server_delete() must be in sync with poll
authorJaroslav Kysela <perex@perex.cz>
Mon, 4 Jan 2016 21:07:08 +0000 (22:07 +0100)
committerJaroslav Kysela <perex@perex.cz>
Mon, 4 Jan 2016 21:07:08 +0000 (22:07 +0100)
src/tcp.c

index 87546b48cc9730d8731e1b89e8accdd769ac9096..2b052edc95384a5ab3a1c0f3f418938d829f7eb9 100644 (file)
--- a/src/tcp.c
+++ b/src/tcp.c
@@ -453,6 +453,7 @@ typedef struct tcp_server {
   struct sockaddr_storage bound;
   tcp_server_ops_t ops;
   void *opaque;
+  LIST_ENTRY(tcp_server) link;
 } tcp_server_t;
 
 typedef struct tcp_server_launch {
@@ -471,6 +472,7 @@ typedef struct tcp_server_launch {
   LIST_ENTRY(tcp_server_launch) jlink;
 } tcp_server_launch_t;
 
+static LIST_HEAD(, tcp_server) tcp_server_delete_list = { 0 };
 static LIST_HEAD(, tcp_server_launch) tcp_server_launches = { 0 };
 static LIST_HEAD(, tcp_server_launch) tcp_server_active = { 0 };
 static LIST_HEAD(, tcp_server_launch) tcp_server_join = { 0 };
@@ -685,6 +687,10 @@ next:
           free(tsl);
           goto next;
         }
+        while ((ts = LIST_FIRST(&tcp_server_delete_list)) != NULL) {
+          LIST_REMOVE(ts, link);
+          free(ts);
+        }
         pthread_mutex_unlock(&global_lock);
       }
       continue;
@@ -919,6 +925,7 @@ tcp_server_delete(void *server)
 {
   tcp_server_t *ts = server;
   tvhpoll_event_t ev;
+  char c = 'D';
 
   if (server == NULL)
     return;
@@ -927,8 +934,9 @@ tcp_server_delete(void *server)
   ev.fd       = ts->serverfd;
   ev.events   = TVHPOLL_IN;
   ev.data.ptr = ts;
-  tvhpoll_rem(tcp_server_poll, &ev, 1);  
-  free(ts);
+  tvhpoll_rem(tcp_server_poll, &ev, 1);
+  LIST_INSERT_HEAD(&tcp_server_delete_list, ts, link);
+  tvh_write(tcp_server_pipe.wr, &c, 1);
 }
 
 /**
@@ -1081,6 +1089,7 @@ tcp_server_init(void)
 void
 tcp_server_done(void)
 {
+  tcp_server_t *ts;
   tcp_server_launch_t *tsl;  
   char c = 'E';
   int64_t t;
@@ -1117,5 +1126,9 @@ tcp_server_done(void)
     free(tsl);
     pthread_mutex_lock(&global_lock);
   }
+  while ((ts = LIST_FIRST(&tcp_server_delete_list)) != NULL) {
+    LIST_REMOVE(ts, link);
+    free(ts);
+  }
   pthread_mutex_unlock(&global_lock);
 }