changeset 16:ecb85bde67b1

added signal handler to perform cleaning up when it receives a signal.
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Wed, 25 Feb 2009 02:35:36 +0900
parents 1b0883b02b4f
children 52c7c7c64ba6
files recpt1/recpt1.c
diffstat 1 files changed, 115 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/recpt1/recpt1.c	Tue Feb 24 23:26:22 2009 +0900
+++ b/recpt1/recpt1.c	Wed Feb 25 02:35:36 2009 +0900
@@ -9,6 +9,7 @@
 #include <math.h>
 #include <unistd.h>
 #include <getopt.h>
+#include <signal.h>
 
 #include <netdb.h>
 #include <arpa/inet.h>
@@ -41,12 +42,12 @@
 {
     int lp;
 
-    for(lp = 0; isdb_t_conv_table[lp].parm_freq != NULL; lp++){
+    for(lp = 0; isdb_t_conv_table[lp].parm_freq != NULL; lp++) {
         /* return entry number in the table when strings match and
          * lengths are same. */
         if((memcmp(isdb_t_conv_table[lp].parm_freq, channel,
                    strlen(channel)) == 0) &&
-           (strlen(channel) == strlen(isdb_t_conv_table[lp].parm_freq))){
+           (strlen(channel) == strlen(isdb_t_conv_table[lp].parm_freq))) {
             return &isdb_t_conv_table[lp];
         }
     }
@@ -194,7 +195,8 @@
                            addr, sizeof(struct sockaddr_in));
                 }
                 free(buf);
-            } else {
+            }
+            else {
                 if(use_udp && sfd != -1) {
                     sendto(sfd, sbuf.data, sbuf.size, 0,
                            addr, sizeof(struct sockaddr_in));
@@ -248,7 +250,8 @@
                            addr, sizeof(struct sockaddr_in));
                 }
                 free(buf);
-            } else {
+            }
+            else {
                 write(wfd, sbuf.data, sbuf.size);
 
                 if(use_udp && sfd != -1) {
@@ -355,13 +358,15 @@
     sigbuf[1] =  (signal & 0xFF);
 
     /* calculate signal level */
-    if(sigbuf[0] <= 0x10U){
+    if(sigbuf[0] <= 0x10U) {
         /* clipped maximum */
         return 24.07f;
-    } else if (sigbuf[0] >= 0xB0U) {
+    }
+    else if (sigbuf[0] >= 0xB0U) {
         /* clipped minimum */
         return 0.0f;
-    } else {
+    }
+    else {
         /* linear interpolation */
         const float fMixRate =
             (float)(((unsigned short)(sigbuf[0] & 0x0FU) << 8) |
@@ -388,12 +393,77 @@
         CNR = (0.000024 * P * P * P * P) - (0.0016 * P * P * P) +
                     (0.0398 * P * P) + (0.5491 * P)+3.0965;
         printf("Signal=%fdB\n", CNR);
-    } else {
+    }
+    else {
         CNR = getsignal_isdb_s(rc);
         printf("Signal=%fdB\n", CNR);
     }
 }
 
+void
+cleanup(int tfd)
+{
+    /* stop recording */
+    ioctl(tfd, STOP_REC, 0);
+
+    /* restore LNB state */
+#if 0
+    if(ptr->type == CHTYPE_SATELLITE) {
+        if(ioctl(tfd, LNB_DISABLE, 0) < 0) {
+            return 0 ;
+        }
+    }
+#endif
+    /* xxx really need mutex? */
+    f_exit = TRUE;
+}
+
+/* will be signal handler thread */
+void *
+process_signals(void *data)
+{
+    sigset_t waitset;
+    int sig;
+    int tfd = *(int *)data;
+
+    sigemptyset(&waitset);
+    sigaddset(&waitset, SIGINT);
+    sigaddset(&waitset, SIGTERM);
+
+    sigwait(&waitset, &sig);
+
+    switch(sig) {
+    case SIGINT:
+        fprintf(stderr, "\nSIGINT received. cleaning up...\n");
+        cleanup(tfd);
+        break;
+    case SIGTERM:
+        fprintf(stderr, "\nSIGTERM received. cleaning up...\n");
+        cleanup(tfd);
+        break;
+    }
+
+    return NULL; /* dummy */
+}
+
+void
+init_signal_handlers(pthread_t *signal_thread, int tfd)
+{
+    sigset_t blockset;
+    static int tunerfd;
+
+    tunerfd = tfd;
+
+    sigemptyset(&blockset);
+    sigaddset(&blockset, SIGINT);
+    sigaddset(&blockset, SIGTERM);
+
+    if(pthread_sigmask(SIG_BLOCK, &blockset, NULL))
+        fprintf(stderr, "pthread_sigmask() failed.\n");
+
+    pthread_create(signal_thread, NULL, process_signals, &tunerfd);
+}
+
 int
 main(int argc, char **argv)
 {
@@ -404,7 +474,8 @@
     time_t start_time, cur_time;
     FREQUENCY freq;
     ISDB_T_FREQ_CONV_TABLE *ptr;
-    pthread_t dequeue_threads;
+    pthread_t dequeue_thread;
+    pthread_t signal_thread;
     QUEUE_T *p_queue = create_queue(MAX_QUEUE);
     BUFSZ   *bufptr;
     decoder *dec = NULL;
@@ -512,10 +583,11 @@
             }
         }
         if(tfd < 0) {
-            fprintf(stderr, "Device Open Error\n");
+            fprintf(stderr, "Cannot open tuner\n");
             return 1;
         }
-    } else {
+    }
+    else {
         for(lp = 0; lp < 2; lp++) {
             tfd = open(isdb_t_dev[lp], O_RDONLY);
             if(tfd >= 0) {
@@ -523,7 +595,7 @@
             }
         }
         if(tfd < 0) {
-            fprintf(stderr, "Device Open Error\n");
+            fprintf(stderr, "Cannot open tuner\n");
             return 1;
         }
     }
@@ -537,8 +609,8 @@
     if(use_b25) {
         dec = b25_startup(&dopt);
         if(!dec) {
-            fprintf(stderr, "cannot start b25 decoder\n");
-            fprintf(stderr, "fall back to encrypted recording\n");
+            fprintf(stderr, "Could not start b25 decoder\n");
+            fprintf(stderr, "Fall back to encrypted recording\n");
             use_b25 = 0;
         }
     }
@@ -569,40 +641,47 @@
     if(!fileless) {
         wfd = open(argv[optind + 2], (O_RDWR | O_CREAT | O_TRUNC), 0666);
         if(wfd < 0) {
-            fprintf(stderr, "Output File Open Error(%s)\n", argv[optind + 2]);
+            fprintf(stderr, "Could not open output file(%s)\n", argv[optind + 2]);
             return 1;
         }
     }
-    if(ptr->type == CHTYPE_SATELLITE){
-        if(ioctl(tfd, LNB_ENABLE, 0) < 0){
+    if(ptr->type == CHTYPE_SATELLITE) {
+        if(ioctl(tfd, LNB_ENABLE, 0) < 0) {
             return 0 ;
         }
     }
 
     if(ioctl(tfd, SET_CHANNEL, &freq) < 0) {
-        fprintf(stderr, "Tuner Select Error\n");
+        fprintf(stderr, "Could not tune to the specified channel\n");
 		calc_cn(tfd, ptr->type);
         return 1;
     }
     calc_cn(tfd, ptr->type);
 
+    /* init signal handler thread */
+    init_signal_handlers(&signal_thread, tfd);
+
     /* make reader thread */
     tdata.queue = p_queue;
     tdata.decoder = dec;
     tdata.wfd = wfd;
     tdata.sock_data = sdata;
-    pthread_create(&dequeue_threads, NULL, write_func, &tdata);
+    pthread_create(&dequeue_thread, NULL, write_func, &tdata);
 
     /* start recording */
     if(ioctl(tfd, START_REC, 0) < 0) {
-        fprintf(stderr, "Tuner Start Error\n");
+        fprintf(stderr, "Tuner could not start recording\n");
         return 1;
     }
 
+    fprintf(stderr, "Recording...\n");
+
     time(&start_time);
 
     /* read from tuner */
     while(1) {
+        if(f_exit)
+            break;
         time(&cur_time);
         bufptr = malloc(sizeof(BUFSZ));
         bufptr->size = read(tfd, bufptr->buffer, MAX_READ_SIZE);
@@ -611,7 +690,8 @@
                 f_exit = TRUE;
                 enqueue(p_queue, NULL);
                 break;
-            } else {
+            }
+            else {
                 continue;
             }
         }
@@ -634,28 +714,34 @@
             break;
         }
     }
+
     /* close tuner */
-    if(ptr->type == CHTYPE_SATELLITE){
-        if(ioctl(tfd, LNB_DISABLE, 0) < 0){
+    if(ptr->type == CHTYPE_SATELLITE) {
+        if(ioctl(tfd, LNB_DISABLE, 0) < 0) {
             return 0 ;
         }
     }
     close(tfd);
 
     /* wait reader thread */
-    pthread_join(dequeue_threads, NULL);
+    pthread_join(dequeue_thread, NULL);
+    fprintf(stderr, "dequeue_thread joined\n");
+
+    pthread_join(signal_thread, NULL);
+    fprintf(stderr, "signal_thread joined\n");
+
+    /* relase queue */
     destroy_queue(p_queue);
 
-    /* close socket */
-    if(use_udp) {
-        close(sdata->sfd);
-        free(sdata);
-    }
+    /* free socket data */
+    free(sdata);
 
     /* release decoder */
     if(use_b25) {
         b25_shutdown(dec);
     }
 
+    fprintf(stderr, "leaving main\n");
+
     return 0;
 }